diff --git a/.gitignore b/.gitignore index c3c1388..e5f87c3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ *.swp node_modules +.DS_Store diff --git a/Gruntfile.js b/Gruntfile.js index 3f0d7a1..bddba8f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -19,7 +19,8 @@ module.exports = function(grunt) { 'lib/cryptojs_v3.1.2.js', 'src/verbs.js', 'src/xapiwrapper.js', - 'src/xapistatement.js' + 'src/xapistatement.js', + 'src/xapi-util.js' ] } } diff --git a/examples/stmtBank.js b/examples/stmtBank.js new file mode 100644 index 0000000..10abece --- /dev/null +++ b/examples/stmtBank.js @@ -0,0 +1,762 @@ +/* +A store of valid xapi statements for testing and coverage purposes. Please use as needed. + +https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md +*/ +(function (obj) { + var ADL = obj; + if (typeof window !== 'undefined') { + ADL = window.ADL = obj.ADL || {}; + } + ADL.stmts = { + /* Requirements: + A Statement MUST use each property no more than one time. + A Statement MUST use “actor”, “verb”, and “object”. + A Statement MAY use its properties in any order. + */ + + /* An example of the simplest possible Statement using all properties that MUST or SHOULD be used: Actor-Verb-Object and Statement Id + */ + "Base-Statement": { + "actor": { + "mbox": "mailto:xapi@adlnet.gov", + "objectType": "Agent" + }, + "verb": { + "id": "http://adlnet.gov/expapi/verbs/created", + "display": { + "en-US": "created" + } + }, + "object": { + "id": "http://example.adlnet.gov/xapi/example/activity", + "objectType": "Activity" + }, + "version": "1.0.1", + "timestamp": "2016-01-25T20:24:01.770727+00:00", + "stored": "2016-01-25T20:24:01.770727+00:00", + "authority": { + "mbox": "mailto:tyler.mulligan.ctr+xapi-tools@adlnet.gov", + "name": "xapi-tools", + "objectType": "Agent" + }, + "id": "12345678-1234-5678-1234-567812345678" + }, + + /* Actor Agent - Simple statement featured at the xapi spec https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#AppendixA + features Actor-Verb-Object with UUID */ + "Actor-Agent": { + "actor": { + "mbox": "mailto:user@example.com", + "name": "Project Tin Can API", + "objectType": "Agent" + }, + "verb": { + "id": "http://adlnet.gov/expapi/verbs/created", + "display": { + "en-US": "created" + } + }, + "version": "1.0.1", + "timestamp": "2016-01-25T20:20:48.295049+00:00", + "object": { + "definition": { + "name": { + "en-US": "simple statement" + }, + "description": { + "en-US": "A simple Experience API statement. Note that the LRS does not need to have any prior information about the Actor (learner), the verb, or the Activity/object." + } + }, + "id": "http://example.adlnet.gov/xapi/example/simplestatement", + "objectType": "Activity" + }, + "stored": "2016-01-25T20:20:48.295049+00:00", + "authority": { + "mbox": "mailto:tyler.mulligan.ctr+xapi-tools@adlnet.gov", + "name": "xapi-tools", + "objectType": "Agent" + }, + "id": "fd41c918-b88b-4b20-a0a5-a4c32391aaa0" + }, + + /* Actor Group - Simple Statment with the Actor of type Identified Group */ + "Actor-Id-Group": { + "actor": { + "member": [ + { + "mbox": "mailto:andrew@example.com", + "name": "Andrew Downes", + "objectType": "Agent" + }, + { + "openid": "http://aaron.openid.example.org", + "name": "Aaron Silvers", + "objectType": "Agent" + } + ], + "account": { + "homePage": "http://example.com/homePage", + "name": "GroupAccount" + }, + "name": "Example Group", + "objectType": "Group" + }, + "verb": { + "id": "http://adlnet.gov/expapi/verbs/created", + "display": { + "en-US": "created" + } + }, + "version": "1.0.1", + "timestamp": "2016-01-25T20:15:46.622339+00:00", + "object": { + "definition": { + "name": { + "en-US": "Example Activity" + }, + "description": { + "en-US": "Example activity description" + } + }, + "id": "http://example.adlnet.gov/xapi/example/activity", + "objectType": "Activity" + }, + "stored": "2016-01-25T20:15:46.622339+00:00", + "authority": { + "mbox": "mailto:tyler.mulligan.ctr+xapi-tools@adlnet.gov", + "name": "xapi-tools", + "objectType": "Agent" + }, + "id": "65135a9a-b656-4445-9ffc-206ff22431c3" + }, + + /* Anonymous Group - the Actor is of type Anonymous Group */ + "Actor-Anon-Group": { + "actor": { + "member": [ + { + "mbox": "mailto:andrew@example.com", + "name": "Andrew Downes", + "objectType": "Agent" + }, + { + "openid": "http://aaron.openid.example.org", + "name": "Aaron Silvers", + "objectType": "Agent" + } + ], + "objectType": "Group" + }, + "verb": { + "id": "http://adlnet.gov/expapi/verbs/completed", + "display": { + "en-US": "completed" + } + }, + "version": "1.0.1", + "timestamp": "2016-01-27T19:12:45.427205+00:00", + "object": { + "definition": { + "name": { + "en-US": "Example Activity" + }, + "description": { + "en-US": "Example activity description" + } + }, + "id": "http://example.adlnet.gov/xapi/example/activity", + "objectType": "Activity" + }, + "stored": "2016-01-27T19:12:45.427205+00:00", + "authority": { + "mbox": "mailto:tyler.mulligan.ctr+xapi-tools@adlnet.gov", + "name": "xapi-tools", + "objectType": "Agent" + }, + "id": "8484d8a3-cd78-4883-bbb7-04bb12409fa9" + }, + + /* Actor Inverse Functional Identifier (IFI) mbox - Simple Statment with the Actor IFI mbox_sha1sum. */ + "Actor-Mbox": { + "actor": { + "mbox_sha1sum": "6a113390c5a05e6e345e0f559e03a1b294c2c3a3", + "objectType": "Agent" + }, + "verb": { + "id": "http://adlnet.gov/expapi/verbs/created", + "display": { + "en-US": "created" + } + }, + "version": "1.0.1", + "timestamp": "2016-01-25T20:10:38.397395+00:00", + "object": { + "definition": { + "name": { + "en-US": "Example Activity" + }, + "description": { + "en-US": "Example activity description" + } + }, + "id": "http://example.adlnet.gov/xapi/example/activity", + "objectType": "Activity" + }, + "stored": "2016-01-25T20:10:38.397395+00:00", + "authority": { + "mbox": "mailto:tyler.mulligan.ctr+xapi-tools@adlnet.gov", + "name": "xapi-tools", + "objectType": "Agent" + }, + "id": "e179532e-ae03-4b86-a84f-aea691f1fd13" + }, + + /* Actor IFI Openid - Simple Statement with the Actor IFI openid */ + "Actor-Openid": { + "actor": { + "openid": "http://user.openid.example.com", + "objectType": "Agent" + }, + "verb": { + "display": { + "en-US": "created" + }, + "id": "http://adlnet.gov/expapi/verbs/created" + }, + "version": "1.0.1", + "timestamp": "2016-01-25T20:05:53.282478+00:00", + "object": { + "definition": { + "description": { + "en-US": "Example activity description" + }, + "name": { + "en-US": "Example Activity" + } + }, + "id": "http://example.adlnet.gov/xapi/example/activity", + "objectType": "Activity" + }, + "stored": "2016-01-25T20:05:53.282478+00:00", + "authority": { + "mbox": "mailto:tyler.mulligan.ctr+xapi-tools@adlnet.gov", + "name": "xapi-tools", + "objectType": "Agent" + }, + "id": "e038d689-2d58-4068-a8c9-2cd51c8aa4c8" + }, + + /* Actor IFI Account - simple statement with the Actor as an account. + A user account on an existing system, such as a private system (LMS or + intranet) or a public system (social networking site). https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#4124-account-object */ + "Actor-Account": { + "actor": { + "account": { + "homePage": "http://www.example.com", + "name": "1625378" + }, + "objectType": "Agent" + }, + "verb": { + "display": { + "en-US": "created" + }, + "id": "http://adlnet.gov/expapi/verbs/created" + }, + "version": "1.0.1", + "timestamp": "2016-01-25T20:00:31.763809+00:00", + "object": { + "definition": { + "description": { + "en-US": "Example activity description" + }, + "name": { + "en-US": "Example Activity" + } + }, + "id": "http://example.adlnet.gov/xapi/example/activity", + "objectType": "Activity" + }, + "stored": "2016-01-25T20:00:31.763809+00:00", + "authority": { + "mbox": "mailto:tyler.mulligan.ctr+xapi-tools@adlnet.gov", + "name": "xapi-tools", + "objectType": "Agent" + }, + "id": "7a886f8b-e1c6-4470-8f33-54810b5a99e5" + }, + + /* Verb - Simple Statement with user defined verb + https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#413-verb */ + "Verb-User-Defined": { + "verb": { + "display": { + "en-US": "perused" + }, + "id": "http://user.com/xapi/verbs/perused" + }, + "id": "591122cf-e208-4503-bcdb-279d4a1129a6", + "version": "1.0.1", + "timestamp": "2016-01-21T16:35:26.532503+00:00", + "actor": { + "openid": "http://user.openid.example.com", + "objectType": "Agent" + }, + "object": { + "definition": { + "description": { + "en-US": "Example activity description" + }, + "name": { + "en-US": "Example Activity" + } + }, + "id": "http://example.adlnet.gov/xapi/example/activity", + "objectType": "Activity" + }, + "stored": "2016-01-21T16:35:26.532503+00:00", + "authority": { + "mbox": "mailto:tyler.mulligan.ctr+xapi-tools@adlnet.gov", + "name": "xapi-tools", + "objectType": "Agent" + } + }, + + /* Verb - Simple Statement with predefined verb */ + "Verb-Predefined": { + "verb": { + "id": "http://adlnet.gov/expapi/verbs/preferred", + "display": { + "en-US": "preferred" + } + }, + "version": "1.0.1", + "timestamp": "2016-01-21T16:30:02.244116+00:00", + "object": { + "definition": { + "name": { + "en-US": "Example Activity" + }, + "description": { + "en-US": "Example activity description" + } + }, + "id": "http://example.adlnet.gov/xapi/example/activity", + "objectType": "Activity" + }, + "actor": { + "openid": "http://user.openid.example.com", + "objectType": "Agent" + }, + "stored": "2016-01-21T16:30:02.244116+00:00", + "authority": { + "mbox": "mailto:tyler.mulligan.ctr+xapi-tools@adlnet.gov", + "name": "xapi-tools", + "objectType": "Agent" + }, + "id": "12d33361-b5fe-48dd-ab8c-8777cc9c45a5" + }, + + /* Object - Simple Statment with Object as an Activity + https://github.com/adlnet/xAPI-Spec/blob/master/xAPI.md#414-object */ + "Object-Activity": { + "object": { + "definition": { + "description": { + "en-US": "Example activity description" + }, + "name": { + "en-US": "Example Activity" + } + }, + "id": "http://example.adlnet.gov/xapi/example/activity", + "objectType": "Activity" + }, + "verb": { + "display": { + "en-US": "attempted" + }, + "id": "http://adlnet.gov/expapi/verbs/attempted" + }, + "version": "1.0.1", + "timestamp": "2016-01-21T16:09:30.685861+00:00", + "actor": { + "mbox": "mailto:user@example.com", + "objectType": "Agent" + }, + "stored": "2016-01-21T16:09:30.685861+00:00", + "authority": { + "mbox": "mailto:tyler.mulligan.ctr+xapi-tools@adlnet.gov", + "name": "xapi-tools", + "objectType": "Agent" + }, + "id": "8d5a014c-0d8d-4bca-be53-d6dba346519b" + }, + + /* Object - Simple Statment with Object as an Agent */ + "Object-Agent": { + "object": { + "mbox": "mailto:instructor@example.com", + "name": "Instructor", + "objectType": "Agent" + }, + "verb": { + "display": { + "en-US": "asked" + }, + "id": "http://adlnet.gov/expapi/verbs/asked" + }, + "version": "1.0.1", + "timestamp": "2016-01-21T15:59:29.050208+00:00", + "actor": { + "mbox": "mailto:user@example.com", + "objectType": "Agent" + }, + "stored": "2016-01-21T15:59:29.050208+00:00", + "authority": { + "mbox": "mailto:tyler.mulligan.ctr+xapi-tools@adlnet.gov", + "name": "xapi-tools", + "objectType": "Agent" + }, + "id": "f3d9ed54-c057-11e5-b464-005056a25e99" + }, + + /* Object - Simple Statement with Object as a Group */ + "Object-Group": { + "object": { + "member": [ + { + "account": { + "homePage": "http://www.example.com", + "name": "13936749" + }, + "name": "Bob", + "objectType": "Agent" + }, + { + "openid": "http://carol.openid.example.org/", + "name": "Carol", + "objectType": "Agent" + }, + { + "mbox": "mailto:tom@example.com", + "name": "Tom", + "objectType": "Agent" + }, + { + "mbox_sha1sum": "ebd31e95054c018b10727de4db3ef2ec3a016ee9", + "name": "Alice", + "objectType": "Agent" + } + ], + "name": "Students", + "objectType": "Group" + }, + "verb": { + "display": { + "en-US": "asked" + }, + "id": "http://adlnet.gov/expapi/verbs/asked" + }, + "version": "1.0.1", + "timestamp": "2016-01-21T15:59:29.027893+00:00", + "actor": { + "mbox": "mailto:user@example.com", + "objectType": "Agent" + }, + "stored": "2016-01-21T15:59:29.027893+00:00", + "authority": { + "mbox": "mailto:tyler.mulligan.ctr+xapi-tools@adlnet.gov", + "name": "xapi-tools", + "objectType": "Agent" + }, + "id": "f3d68632-c057-11e5-b464-005056a25e99" + }, + + /* Object - Simple Statement with Object as a Statement Reference*/ + "Object-StatementRef": { + "object": { + "id": "12345678-1234-5678-1234-567812345678", + "objectType": "StatementRef" + }, + "actor": { + "mbox": "mailto:user@example.com", + "objectType": "Agent" + }, + "verb": { + "id": "http://adlnet.gov/expapi/verbs/asked", + "display": { + "en-US": "asked" + } + }, + "version": "1.0.1", + "timestamp": "2016-01-21T15:59:29.017173+00:00", + "stored": "2016-01-21T15:59:29.017173+00:00", + "authority": { + "mbox": "mailto:tyler.mulligan.ctr+xapi-tools@adlnet.gov", + "name": "xapi-tools", + "objectType": "Agent" + }, + "id": "f3d4e214-c057-11e5-b464-005056a25e99" + }, + + /* Object - Simple Statement with Object as a Sub-Statement */ + "Object-Sub-Statement": { + "verb": { + "id": "http://example.com/planned", + "display": { + "en-US": "planned" + } + }, + "version": "1.0.1", + "timestamp": "2016-01-26T19:28:25.096469+00:00", + "object": { + "verb": { + "id": "http://example.com/visited", + "display": { + "en-US": "will visit" + } + }, + "actor": { + "mbox": "mailto:test@example.com", + "objectType": "Agent" + }, + "object": { + "definition": { + "name": { + "en-US": "Some Awesome Website" + } + }, + "id": "http://example.com/website", + "objectType": "Activity" + }, + "objectType": "SubStatement" + }, + "actor": { + "mbox": "mailto:test@example.com", + "objectType": "Agent" + }, + "stored": "2016-01-26T19:28:25.096469+00:00", + "authority": { + "mbox": "mailto:tyler.mulligan.ctr+xapi-tools@adlnet.gov", + "name": "xapi-tools", + "objectType": "Agent" + }, + "id": "29cf2f86-3f41-4efc-8f64-866c3ce8899c" + }, + + /* Simple statement with Object as a Sub-Statement whose Object is a Statement Reference*/ + "Object-Sub-Statement-with-StatementRef": { + "verb": { + "id": "http://verb.com/do0" + }, + "version": "1.0.1", + "timestamp": "2016-01-25T20:28:19.597807+00:00", + "object": { + "verb": { + "id": "http://example.com/confirmed", + "display": { + "en": "confirmed" + } + }, + "actor": { + "mbox": "mailto:agent@example.com", + "objectType": "Agent" + }, + "object": { + "id": "9e13cefd-53d3-4eac-b5ed-2cf6693903bb", + "objectType": "StatementRef" + }, + "objectType": "SubStatement" + }, + "actor": { + "mbox": "mailto:tom@tom.com", + "objectType": "Agent" + }, + "stored": "2016-01-25T20:28:19.597807+00:00", + "authority": { + "mbox": "mailto:tyler.mulligan.ctr+xapi-tools@adlnet.gov", + "name": "xapi-tools", + "objectType": "Agent" + }, + "id": "b5f9eb2c-588f-48b0-b845-71ed17cd074e" + }, + + /* Result section */ + "Result": { + "verb": { + "id": "http://adlnet.gov/expapi/verbs/attempted", + "display": { + "en-US": "attempted" + } + }, + "version": "1.0.1", + "timestamp": "2016-01-25T20:40:21.350153+00:00", + "object": { + "definition": { + "name": { + "en-US": "simple CBT course" + }, + "description": { + "en-US": "A fictitious example CBT course." + } + }, + "id": "http://example.adlnet.gov/xapi/example/simpleCBT", + "objectType": "Activity" + }, + "actor": { + "mbox": "mailto:example.learner@adlnet.gov", + "name": "Example Learner", + "objectType": "Agent" + }, + "stored": "2016-01-25T20:40:21.350153+00:00", + "result": { + "completion": true, + "score": { + "scaled": 0.95 + }, + "success": true + }, + "id": "0c808355-396c-4a3f-9bf2-5334e0f71493", + "authority": { + "mbox": "mailto:tyler.mulligan.ctr+xapi-tools@adlnet.gov", + "name": "xapi-tools", + "objectType": "Agent" + } + }, + + /* A long example statement showcasing most of the properties available. This example shows a statement returned by an LRS including the authority and stored properties set by the LRS */ + "Long-Example": { + "id": "6690e6c9-3ef0-4ed3-8b37-7f3964730bee", + "actor": { + "name": "Team PB", + "mbox": "mailto:teampb@example.com", + "member": [ + { + "name": "Andrew Downes", + "account": { + "homePage": "http://www.example.com", + "name": "13936749" + }, + "objectType": "Agent" + }, + { + "name": "Toby Nichols", + "openid": "http://toby.openid.example.org/", + "objectType": "Agent" + }, + { + "name": "Ena Hills", + "mbox_sha1sum": "ebd31e95054c018b10727ccffd2ef2ec3a016ee9", + "objectType": "Agent" + } + ], + "objectType": "Group" + }, + "verb": { + "id": "http://adlnet.gov/expapi/verbs/attended", + "display": { + "en-GB": "attended", + "en-US": "attended" + } + }, + "result": { + "extensions": { + "http://example.com/profiles/meetings/resultextensions/minuteslocation": "X:\\meetings\\minutes\\examplemeeting.one" + }, + "success": true, + "completion": true, + "response": "We agreed on some example actions.", + "duration": "PT1H0M0S" + }, + "context": { + "registration": "ec531277-b57b-4c15-8d91-d292c5b2b8f7", + "contextActivities": { + "parent": [ + { + "id": "http://www.example.com/meetings/series/267", + "objectType": "Activity" + } + ], + "category": [ + { + "id": "http://www.example.com/meetings/categories/teammeeting", + "objectType": "Activity", + "definition": { + "name": { + "en": "team meeting" + }, + "description": { + "en": "A category of meeting used for regular team meetings." + }, + "type": "http://example.com/expapi/activities/meetingcategory" + } + } + ], + "other": [ + { + "id": "http://www.example.com/meetings/occurances/34257", + "objectType": "Activity" + }, + { + "id": "http://www.example.com/meetings/occurances/3425567", + "objectType": "Activity" + } + ] + }, + "instructor" : + { + "name": "Andrew Downes", + "account": { + "homePage": "http://www.example.com", + "name": "13936749" + }, + "objectType": "Agent" + }, + "team": + { + "name": "Team PB", + "mbox": "mailto:teampb@example.com", + "objectType": "Group" + }, + "platform" : "Example virtual meeting software", + "language" : "tlh", + "statement" : { + "objectType":"StatementRef", + "id" :"6690e6c9-3ef0-4ed3-8b37-7f3964730bee" + } + + }, + "timestamp": "2013-05-18T05:32:34.804Z", + "stored": "2013-05-18T05:32:34.804Z", + "authority": { + "account": { + "homePage": "http://cloud.scorm.com/", + "name": "anonymous" + }, + "objectType": "Agent" + }, + "version": "1.0.0", + "object": { + "id": "http://www.example.com/meetings/occurances/34534", + "definition": { + "extensions": { + "http://example.com/profiles/meetings/activitydefinitionextensions/room": {"name": "Kilby", "id" : "http://example.com/rooms/342"} + }, + "name": { + "en-GB": "example meeting", + "en-US": "example meeting" + }, + "description": { + "en-GB": "An example meeting that happened on a specific occasion with certain people present.", + "en-US": "An example meeting that happened on a specific occasion with certain people present." + }, + "type": "http://adlnet.gov/expapi/activities/meeting", + "moreInfo": "http://virtualmeeting.example.com/345256" + }, + "objectType": "Activity" + } + }, + } +})(this); diff --git a/src/xapi-util.js b/src/xapi-util.js new file mode 100644 index 0000000..94bcb98 --- /dev/null +++ b/src/xapi-util.js @@ -0,0 +1,157 @@ +(function (obj) { + var ADL = obj; + var onBrowser = false; + if (typeof window !== 'undefined') { + ADL = window.ADL = obj.ADL || {}; + onBrowser = true; + } + + var getObjDefName = function (o) { + if (o.definition && o.definition.name) { + return ADL.xapiutil.getLangVal(o.definition.name); + } + return undefined; + }; + + var getSubStatementDisplay = function (o) { + if(o.objectType !== "SubStatement") return; + if(o.object.objectType === "SubStatement") return; + if(o.id || o.stored || o.version || o.authority) return; + var disp = ADL.xapiutil.getActorId(o.actor) + ":" + ADL.xapiutil.getVerbDisplay(o.verb) + ":" + ADL.xapiutil.getObjectId(o.object); + return disp; + }; + + + ADL.xapiutil = {}; + + ADL.xapiutil.getLang = function () { + var lang; + if (typeof navigator !== 'undefined') + lang = navigator.language || navigator.browserLanguage || + navigator.systemLanguage || navigator.userLanguage; + else if (process && process.env) { + var str = process.env.LANG; + lang = str.slice(0, str.indexOf('.')); + lang = lang.replace(/_/, '-') + } + return lang || "en-US"; + }; + + ADL.xapiutil.getLangVal = function (langprop) { + + if (!langprop) return; + + var options = Object.keys(langprop); + // test that langprop is a dict (obj) + // skips if not a dict(obj) and returns + if (options.length == 0) return undefined; + + var lang = ADL.xapiutil.getLang(), + ret, + dispGotten = false; + + do { //test and retest + if (langprop[lang]) + { + ret = langprop[lang]; + dispGotten = true; + } + else if (lang.indexOf('-')) + { + lang = lang.substring(0, lang.lastIndexOf('-')); + } + } while (!dispGotten && lang !==""); + + return ret; + }; + + ADL.xapiutil.getMoreStatements = function (iterations, callback, searchParams) { + if (!onBrowser) throw new Error("Node not supported."); + + var stmts = []; + + ADL.XAPIWrapper.getStatements(searchParams, null, function getMore(r) { + if (! (r && r.response) ) return; + var res = JSON.parse(r.response); + if (! res.statements) return; + stmts = stmts.concat(res.statements); + + if (iterations-- <= 0) { + callback(stmts); + } + else { + if (res.more && res.more !== "") + { + ADL.XAPIWrapper.getStatements(searchParams, res.more, getMore); + } + else if (res.more === "") + { + callback(stmts); + } + } + }); + }; + + ADL.xapiutil.getActorId = function (a) { + return a.mbox || a.openid || a.mbox_sha1sum || a.account; + }; + + ADL.xapiutil.getActorIdString = function (a) { + var id = a.mbox || a.openid || a.mbox_sha1sum; + if (! id) { + if (a.account) id = a.account.homePage + ":" + a.account.name; + else if (a.member) id = "Anon Group " + a.member; + else id = 'unknown'; + } + return id; + }; + + ADL.xapiutil.getActorDisplay = function (a) { + return a.name || ADL.xapiutil.getActorIdString(a); + }; + + ADL.xapiutil.getVerbDisplay = function (v) { + if (!v) return; + if (v.display) { + return ADL.xapiutil.getLangVal(v.display) || v.id; + } + return v.id; + }; + + ADL.xapiutil.getObjectType = function (o) { + return o.objectType || ((o.id) ? "Activity" : "Agent"); + }; + + ADL.xapiutil.getObjectId = function (o) { + if (o.id) return o.id; + var type = ADL.xapiutil.getObjectType(o); + if (type === "Agent" || type === "Group") return ADL.xapiutil.getActorId(o); + return undefined; + }; + + ADL.xapiutil.getObjectIdString = function (o) { + if (!o) return 'unknown' + if (o.id) return o.id; + var type = ADL.xapiutil.getObjectType(o); + if (type === "Agent" || type === "Group") return ADL.xapiutil.getActorIdString(o); + else if (type == "SubStatement") { + return getSubStatementDisplay(o); + } + return 'unknown'; + }; + + ADL.xapiutil.getObjectDisplay = function (o) { + if (!o) return "unknown" + var disp = getObjDefName(o) || o.name || o.id; + if (! disp) { + var type = ADL.xapiutil.getObjectType(o); + if (type === "Agent" || type == "Group") disp = ADL.xapiutil.getActorDisplay(o); + else if (type == "SubStatement") { + disp = getSubStatementDisplay(o); + } + } + + return disp; + }; + +})(this); diff --git a/test/README.md b/test/README.md new file mode 100644 index 0000000..ccf132c --- /dev/null +++ b/test/README.md @@ -0,0 +1,41 @@ +# Testing xAPI-Util + +Tests the functionality of /src/xapi-util.js. The test can be run in both a browser or in node. + +For both/either: + +* Clone the repository to your machine + ``` + .../workspace + $ git clone https://github.com/adlnet/xAPIWrapper.git + ``` + +## Browser + +From a browser: + +* Use the terminal to start a server in the xAPIWrapper folder + ``` + .../xAPIWrapper + $ http-server + Starting up http-server, serving ./ + Available on: + http:172.16.0.111:8080 + http:127.0.0.1:8080 + Hit CTRL-C to stop the server + + ``` +* With the browser navigate to /test/testUtil.html + `http://localhost:8080/test/testUtil.html` +* The tests will automatically run displaying the results: passes, failures, duration, percentage. Below the test results, code coverage results are displayed. + +## Node + +* In the terminal navigate to the xAPIWrapper folder +* Use the command + ``` + .../xAPIWrapper + $ mocha test/tests/test.util.js + + ``` +* The tests will run displaying the information in the terminal including results: passing, failing, milliseconds to complete, and a stack trace of any failing tests. diff --git a/test/libs/blanket_mocha.min.js b/test/libs/blanket_mocha.min.js new file mode 100644 index 0000000..07d209c --- /dev/null +++ b/test/libs/blanket_mocha.min.js @@ -0,0 +1,46 @@ +/*! blanket - v1.2.1 */ +!function(a){!function(b){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=b();else if("function"==typeof a&&a.amd)a([],b);else{var c;c="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,c.acorn=b()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g=3&&(d.depth=arguments[2]),arguments.length>=4&&(d.colors=arguments[3]),p(b)?d.showHidden=b:b&&c._extend(d,b),v(d.showHidden)&&(d.showHidden=!1),v(d.depth)&&(d.depth=2),v(d.colors)&&(d.colors=!1),v(d.customInspect)&&(d.customInspect=!0),d.colors&&(d.stylize=f),i(d,a,d.depth)}function f(a,b){var c=e.styles[b];return c?"["+e.colors[c][0]+"m"+a+"["+e.colors[c][1]+"m":a}function g(a,b){return a}function h(a){var b={};return a.forEach(function(a,c){b[a]=!0}),b}function i(a,b,d){if(a.customInspect&&b&&A(b.inspect)&&b.inspect!==c.inspect&&(!b.constructor||b.constructor.prototype!==b)){var e=b.inspect(d,a);return t(e)||(e=i(a,e,d)),e}var f=j(a,b);if(f)return f;var g=Object.keys(b),p=h(g);if(a.showHidden&&(g=Object.getOwnPropertyNames(b)),z(b)&&(g.indexOf("message")>=0||g.indexOf("description")>=0))return k(b);if(0===g.length){if(A(b)){var q=b.name?": "+b.name:"";return a.stylize("[Function"+q+"]","special")}if(w(b))return a.stylize(RegExp.prototype.toString.call(b),"regexp");if(y(b))return a.stylize(Date.prototype.toString.call(b),"date");if(z(b))return k(b)}var r="",s=!1,u=["{","}"];if(o(b)&&(s=!0,u=["[","]"]),A(b)){var v=b.name?": "+b.name:"";r=" [Function"+v+"]"}if(w(b)&&(r=" "+RegExp.prototype.toString.call(b)),y(b)&&(r=" "+Date.prototype.toUTCString.call(b)),z(b)&&(r=" "+k(b)),0===g.length&&(!s||0==b.length))return u[0]+r+u[1];if(0>d)return w(b)?a.stylize(RegExp.prototype.toString.call(b),"regexp"):a.stylize("[Object]","special");a.seen.push(b);var x;return x=s?l(a,b,d,p,g):g.map(function(c){return m(a,b,d,p,c,s)}),a.seen.pop(),n(x,r,u)}function j(a,b){if(v(b))return a.stylize("undefined","undefined");if(t(b)){var c="'"+JSON.stringify(b).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return a.stylize(c,"string")}return s(b)?a.stylize(""+b,"number"):p(b)?a.stylize(""+b,"boolean"):q(b)?a.stylize("null","null"):void 0}function k(a){return"["+Error.prototype.toString.call(a)+"]"}function l(a,b,c,d,e){for(var f=[],g=0,h=b.length;h>g;++g)F(b,String(g))?f.push(m(a,b,c,d,String(g),!0)):f.push("");return e.forEach(function(e){e.match(/^\d+$/)||f.push(m(a,b,c,d,e,!0))}),f}function m(a,b,c,d,e,f){var g,h,j;if(j=Object.getOwnPropertyDescriptor(b,e)||{value:b[e]},j.get?h=j.set?a.stylize("[Getter/Setter]","special"):a.stylize("[Getter]","special"):j.set&&(h=a.stylize("[Setter]","special")),F(d,e)||(g="["+e+"]"),h||(a.seen.indexOf(j.value)<0?(h=q(c)?i(a,j.value,null):i(a,j.value,c-1),h.indexOf("\n")>-1&&(h=f?h.split("\n").map(function(a){return" "+a}).join("\n").substr(2):"\n"+h.split("\n").map(function(a){return" "+a}).join("\n"))):h=a.stylize("[Circular]","special")),v(g)){if(f&&e.match(/^\d+$/))return h;g=JSON.stringify(""+e),g.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(g=g.substr(1,g.length-2),g=a.stylize(g,"name")):(g=g.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),g=a.stylize(g,"string"))}return g+": "+h}function n(a,b,c){var d=0,e=a.reduce(function(a,b){return d++,b.indexOf("\n")>=0&&d++,a+b.replace(/\u001b\[\d\d?m/g,"").length+1},0);return e>60?c[0]+(""===b?"":b+"\n ")+" "+a.join(",\n ")+" "+c[1]:c[0]+b+" "+a.join(", ")+" "+c[1]}function o(a){return Array.isArray(a)}function p(a){return"boolean"==typeof a}function q(a){return null===a}function r(a){return null==a}function s(a){return"number"==typeof a}function t(a){return"string"==typeof a}function u(a){return"symbol"==typeof a}function v(a){return void 0===a}function w(a){return x(a)&&"[object RegExp]"===C(a)}function x(a){return"object"==typeof a&&null!==a}function y(a){return x(a)&&"[object Date]"===C(a)}function z(a){return x(a)&&("[object Error]"===C(a)||a instanceof Error)}function A(a){return"function"==typeof a}function B(a){return null===a||"boolean"==typeof a||"number"==typeof a||"string"==typeof a||"symbol"==typeof a||"undefined"==typeof a}function C(a){return Object.prototype.toString.call(a)}function D(a){return 10>a?"0"+a.toString(10):a.toString(10)}function E(){var a=new Date,b=[D(a.getHours()),D(a.getMinutes()),D(a.getSeconds())].join(":");return[a.getDate(),J[a.getMonth()],b].join(" ")}function F(a,b){return Object.prototype.hasOwnProperty.call(a,b)} +// 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 G=/%[sdj%]/g;c.format=function(a){if(!t(a)){for(var b=[],c=0;c=f)return a;switch(a){case"%s":return String(d[c++]);case"%d":return Number(d[c++]);case"%j":try{return JSON.stringify(d[c++])}catch(b){return"[Circular]"}default:return a}}),h=d[c];f>c;h=d[++c])g+=q(h)||!x(h)?" "+h:" "+e(h);return g},c.deprecate=function(a,e){function f(){if(!g){if(b.throwDeprecation)throw new Error(e);b.traceDeprecation?console.trace(e):console.error(e),g=!0}return a.apply(this,arguments)}if(v(d.process))return function(){return c.deprecate(a,e).apply(this,arguments)};if(b.noDeprecation===!0)return a;var g=!1;return f};var H,I={};c.debuglog=function(a){if(v(H)&&(H=b.env.NODE_DEBUG||""),a=a.toUpperCase(),!I[a])if(new RegExp("\\b"+a+"\\b","i").test(H)){var d=b.pid;I[a]=function(){var b=c.format.apply(c,arguments);console.error("%s %d: %s",a,d,b)}}else I[a]=function(){};return I[a]},c.inspect=e,e.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]},e.styles={special:"cyan",number:"yellow","boolean":"yellow",undefined:"grey","null":"bold",string:"green",date:"magenta",regexp:"red"},c.isArray=o,c.isBoolean=p,c.isNull=q,c.isNullOrUndefined=r,c.isNumber=s,c.isString=t,c.isSymbol=u,c.isUndefined=v,c.isRegExp=w,c.isObject=x,c.isDate=y,c.isError=z,c.isFunction=A,c.isPrimitive=B,c.isBuffer=a("./support/isBuffer");var J=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];c.log=function(){console.log("%s - %s",E(),c.format.apply(c,arguments))},c.inherits=a("inherits"),c._extend=function(a,b){if(!b||!x(b))return a;for(var c=Object.keys(b),d=c.length;d--;)a[c[d]]=b[c[d]];return a}}).call(this,a("_process"),"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./support/isBuffer":4,_process:3,inherits:2}],6:[function(a,b,c){"use strict";var d=a("./tokentype").types,e=a("./state").Parser,f=a("./identifier").reservedWords,g=a("./util").has,h=e.prototype;h.checkPropClash=function(a,b){if(!(this.options.ecmaVersion>=6)){var c=a.key,d=void 0;switch(c.type){case"Identifier":d=c.name;break;case"Literal":d=String(c.value);break;default:return}var e=a.kind||"init",f=void 0;if(g(b,d)){f=b[d];var h="init"!==e;((this.strict||h)&&f[e]||!(h^f.init))&&this.raise(c.start,"Redefinition of property")}else f=b[d]={init:!1,get:!1,set:!1};f[e]=!0}},h.parseExpression=function(a,b){var c=this.start,e=this.startLoc,f=this.parseMaybeAssign(a,b);if(this.type===d.comma){var g=this.startNodeAt(c,e);for(g.expressions=[f];this.eat(d.comma);)g.expressions.push(this.parseMaybeAssign(a,b));return this.finishNode(g,"SequenceExpression")}return f},h.parseMaybeAssign=function(a,b,c){if(this.type==d._yield&&this.inGenerator)return this.parseYield();var e=void 0;b?e=!1:(b={start:0},e=!0);var f=this.start,g=this.startLoc;(this.type==d.parenL||this.type==d.name)&&(this.potentialArrowAt=this.start);var h=this.parseMaybeConditional(a,b);if(c&&(h=c.call(this,h,f,g)),this.type.isAssign){var i=this.startNodeAt(f,g);return i.operator=this.value,i.left=this.type===d.eq?this.toAssignable(h):h,b.start=0,this.checkLVal(h),this.next(),i.right=this.parseMaybeAssign(a),this.finishNode(i,"AssignmentExpression")}return e&&b.start&&this.unexpected(b.start),h},h.parseMaybeConditional=function(a,b){var c=this.start,e=this.startLoc,f=this.parseExprOps(a,b);if(b&&b.start)return f;if(this.eat(d.question)){var g=this.startNodeAt(c,e);return g.test=f,g.consequent=this.parseMaybeAssign(),this.expect(d.colon),g.alternate=this.parseMaybeAssign(a),this.finishNode(g,"ConditionalExpression")}return f},h.parseExprOps=function(a,b){var c=this.start,d=this.startLoc,e=this.parseMaybeUnary(b);return b&&b.start?e:this.parseExprOp(e,c,d,-1,a)},h.parseExprOp=function(a,b,c,e,f){var g=this.type.binop;if(Array.isArray(b)&&this.options.locations&&void 0===f&&(f=e,e=c,c=b[1],b=b[0]),null!=g&&(!f||this.type!==d._in)&&g>e){var h=this.startNodeAt(b,c);h.left=a,h.operator=this.value;var i=this.type;this.next();var j=this.start,k=this.startLoc;return h.right=this.parseExprOp(this.parseMaybeUnary(),j,k,g,f),this.finishNode(h,i===d.logicalOR||i===d.logicalAND?"LogicalExpression":"BinaryExpression"),this.parseExprOp(h,b,c,e,f)}return a},h.parseMaybeUnary=function(a){if(this.type.prefix){var b=this.startNode(),c=this.type===d.incDec;return b.operator=this.value,b.prefix=!0,this.next(),b.argument=this.parseMaybeUnary(),a&&a.start&&this.unexpected(a.start),c?this.checkLVal(b.argument):this.strict&&"delete"===b.operator&&"Identifier"===b.argument.type&&this.raise(b.start,"Deleting local variable in strict mode"),this.finishNode(b,c?"UpdateExpression":"UnaryExpression")}var e=this.start,f=this.startLoc,g=this.parseExprSubscripts(a);if(a&&a.start)return g;for(;this.type.postfix&&!this.canInsertSemicolon();){var b=this.startNodeAt(e,f);b.operator=this.value,b.prefix=!1,b.argument=g,this.checkLVal(g),this.next(),g=this.finishNode(b,"UpdateExpression")}return g},h.parseExprSubscripts=function(a){var b=this.start,c=this.startLoc,d=this.parseExprAtom(a);return a&&a.start?d:this.parseSubscripts(d,b,c)},h.parseSubscripts=function(a,b,c,e){for(Array.isArray(b)&&this.options.locations&&void 0===e&&(e=c,c=b[1],b=b[0]);;)if(this.eat(d.dot)){var f=this.startNodeAt(b,c);f.object=a,f.property=this.parseIdent(!0),f.computed=!1,a=this.finishNode(f,"MemberExpression")}else if(this.eat(d.bracketL)){var f=this.startNodeAt(b,c);f.object=a,f.property=this.parseExpression(),f.computed=!0,this.expect(d.bracketR),a=this.finishNode(f,"MemberExpression")}else if(!e&&this.eat(d.parenL)){var f=this.startNodeAt(b,c);f.callee=a,f.arguments=this.parseExprList(d.parenR,!1),a=this.finishNode(f,"CallExpression")}else{if(this.type!==d.backQuote)return a;var f=this.startNodeAt(b,c);f.tag=a,f.quasi=this.parseTemplate(),a=this.finishNode(f,"TaggedTemplateExpression")}},h.parseExprAtom=function(a){var b=void 0,c=this.potentialArrowAt==this.start;switch(this.type){case d._this:case d._super:var e=this.type===d._this?"ThisExpression":"Super";return b=this.startNode(),this.next(),this.finishNode(b,e);case d._yield:this.inGenerator&&this.unexpected();case d.name:var f=this.start,g=this.startLoc,h=this.parseIdent(this.type!==d.name);return c&&!this.canInsertSemicolon()&&this.eat(d.arrow)?this.parseArrowExpression(this.startNodeAt(f,g),[h]):h;case d.regexp:var i=this.value;return b=this.parseLiteral(i.value),b.regex={pattern:i.pattern,flags:i.flags},b;case d.num:case d.string:return this.parseLiteral(this.value);case d._null:case d._true:case d._false:return b=this.startNode(),b.value=this.type===d._null?null:this.type===d._true,b.raw=this.type.keyword,this.next(),this.finishNode(b,"Literal");case d.parenL:return this.parseParenAndDistinguishExpression(c);case d.bracketL:return b=this.startNode(),this.next(),this.options.ecmaVersion>=7&&this.type===d._for?this.parseComprehension(b,!1):(b.elements=this.parseExprList(d.bracketR,!0,!0,a),this.finishNode(b,"ArrayExpression"));case d.braceL:return this.parseObj(!1,a);case d._function:return b=this.startNode(),this.next(),this.parseFunction(b,!1);case d._class:return this.parseClass(this.startNode(),!1);case d._new:return this.parseNew();case d.backQuote:return this.parseTemplate();default:this.unexpected()}},h.parseLiteral=function(a){var b=this.startNode();return b.value=a,b.raw=this.input.slice(this.start,this.end),this.next(),this.finishNode(b,"Literal")},h.parseParenExpression=function(){this.expect(d.parenL);var a=this.parseExpression();return this.expect(d.parenR),a},h.parseParenAndDistinguishExpression=function(a){var b=this.start,c=this.startLoc,e=void 0;if(this.options.ecmaVersion>=6){if(this.next(),this.options.ecmaVersion>=7&&this.type===d._for)return this.parseComprehension(this.startNodeAt(b,c),!0);for(var f=this.start,g=this.startLoc,h=[],i=!0,j={start:0},k=void 0,l=void 0;this.type!==d.parenR;){if(i?i=!1:this.expect(d.comma),this.type===d.ellipsis){k=this.start,h.push(this.parseParenItem(this.parseRest()));break}this.type!==d.parenL||l||(l=this.start),h.push(this.parseMaybeAssign(!1,j,this.parseParenItem))}var m=this.start,n=this.startLoc;if(this.expect(d.parenR),a&&!this.canInsertSemicolon()&&this.eat(d.arrow))return l&&this.unexpected(l),this.parseParenArrowList(b,c,h);h.length||this.unexpected(this.lastTokStart),k&&this.unexpected(k),j.start&&this.unexpected(j.start),h.length>1?(e=this.startNodeAt(f,g),e.expressions=h,this.finishNodeAt(e,"SequenceExpression",m,n)):e=h[0]}else e=this.parseParenExpression();if(this.options.preserveParens){var o=this.startNodeAt(b,c);return o.expression=e,this.finishNode(o,"ParenthesizedExpression")}return e},h.parseParenItem=function(a){return a},h.parseParenArrowList=function(a,b,c){return this.parseArrowExpression(this.startNodeAt(a,b),c)};var i=[];h.parseNew=function(){var a=this.startNode(),b=this.parseIdent(!0);if(this.options.ecmaVersion>=6&&this.eat(d.dot))return a.meta=b,a.property=this.parseIdent(!0),"target"!==a.property.name&&this.raise(a.property.start,"The only valid meta property for new is new.target"),this.finishNode(a,"MetaProperty");var c=this.start,e=this.startLoc;return a.callee=this.parseSubscripts(this.parseExprAtom(),c,e,!0),this.eat(d.parenL)?a.arguments=this.parseExprList(d.parenR,!1):a.arguments=i,this.finishNode(a,"NewExpression")},h.parseTemplateElement=function(){var a=this.startNode();return a.value={raw:this.input.slice(this.start,this.end),cooked:this.value},this.next(),a.tail=this.type===d.backQuote,this.finishNode(a,"TemplateElement")},h.parseTemplate=function(){var a=this.startNode();this.next(),a.expressions=[];var b=this.parseTemplateElement();for(a.quasis=[b];!b.tail;)this.expect(d.dollarBraceL),a.expressions.push(this.parseExpression()),this.expect(d.braceR),a.quasis.push(b=this.parseTemplateElement());return this.next(),this.finishNode(a,"TemplateLiteral")},h.parseObj=function(a,b){var c=this.startNode(),e=!0,f={};for(c.properties=[],this.next();!this.eat(d.braceR);){if(e)e=!1;else if(this.expect(d.comma),this.afterTrailingComma(d.braceR))break;var g=this.startNode(),h=void 0,i=void 0,j=void 0;this.options.ecmaVersion>=6&&(g.method=!1,g.shorthand=!1,(a||b)&&(i=this.start,j=this.startLoc),a||(h=this.eat(d.star))),this.parsePropertyName(g),this.parsePropertyValue(g,a,h,i,j,b),this.checkPropClash(g,f),c.properties.push(this.finishNode(g,"Property"))}return this.finishNode(c,a?"ObjectPattern":"ObjectExpression")},h.parsePropertyValue=function(a,b,c,e,g,h){this.eat(d.colon)?(a.value=b?this.parseMaybeDefault(this.start,this.startLoc):this.parseMaybeAssign(!1,h),a.kind="init"):this.options.ecmaVersion>=6&&this.type===d.parenL?(b&&this.unexpected(),a.kind="init",a.method=!0,a.value=this.parseMethod(c)):this.options.ecmaVersion>=5&&!a.computed&&"Identifier"===a.key.type&&("get"===a.key.name||"set"===a.key.name)&&this.type!=d.comma&&this.type!=d.braceR?((c||b)&&this.unexpected(),a.kind=a.key.name,this.parsePropertyName(a),a.value=this.parseMethod(!1)):this.options.ecmaVersion>=6&&!a.computed&&"Identifier"===a.key.type?(a.kind="init",b?((this.isKeyword(a.key.name)||this.strict&&(f.strictBind(a.key.name)||f.strict(a.key.name))||!this.options.allowReserved&&this.isReservedWord(a.key.name))&&this.raise(a.key.start,"Binding "+a.key.name),a.value=this.parseMaybeDefault(e,g,a.key)):this.type===d.eq&&h?(h.start||(h.start=this.start),a.value=this.parseMaybeDefault(e,g,a.key)):a.value=a.key,a.shorthand=!0):this.unexpected()},h.parsePropertyName=function(a){if(this.options.ecmaVersion>=6){if(this.eat(d.bracketL))return a.computed=!0,a.key=this.parseMaybeAssign(),this.expect(d.bracketR),a.key;a.computed=!1}return a.key=this.type===d.num||this.type===d.string?this.parseExprAtom():this.parseIdent(!0)},h.initFunction=function(a){a.id=null,this.options.ecmaVersion>=6&&(a.generator=!1,a.expression=!1)},h.parseMethod=function(a){var b=this.startNode();this.initFunction(b),this.expect(d.parenL),b.params=this.parseBindingList(d.parenR,!1,!1);var c=void 0;return this.options.ecmaVersion>=6?(b.generator=a,c=!0):c=!1,this.parseFunctionBody(b,c),this.finishNode(b,"FunctionExpression")},h.parseArrowExpression=function(a,b){return this.initFunction(a),a.params=this.toAssignableList(b,!0),this.parseFunctionBody(a,!0),this.finishNode(a,"ArrowFunctionExpression")},h.parseFunctionBody=function(a,b){var c=b&&this.type!==d.braceL;if(c)a.body=this.parseMaybeAssign(),a.expression=!0;else{var e=this.inFunction,f=this.inGenerator,g=this.labels;this.inFunction=!0,this.inGenerator=a.generator,this.labels=[],a.body=this.parseBlock(!0),a.expression=!1,this.inFunction=e,this.inGenerator=f,this.labels=g}if(this.strict||!c&&a.body.body.length&&this.isUseStrict(a.body.body[0])){var h={},i=this.strict;this.strict=!0,a.id&&this.checkLVal(a.id,!0);for(var j=0;j=6||-1==this.input.slice(this.start,this.end).indexOf("\\")))&&this.raise(this.start,"The keyword '"+this.value+"' is reserved"),b.name=this.value):a&&this.type.keyword?b.name=this.type.keyword:this.unexpected(),this.next(),this.finishNode(b,"Identifier")},h.parseYield=function(){var a=this.startNode();return this.next(),this.type==d.semi||this.canInsertSemicolon()||this.type!=d.star&&!this.type.startsExpr?(a.delegate=!1,a.argument=null):(a.delegate=this.eat(d.star),a.argument=this.parseMaybeAssign()),this.finishNode(a,"YieldExpression")},h.parseComprehension=function(a,b){for(a.blocks=[];this.type===d._for;){var c=this.startNode();this.next(),this.expect(d.parenL),c.left=this.parseBindingAtom(),this.checkLVal(c.left,!0),this.expectContextual("of"),c.right=this.parseExpression(),this.expect(d.parenR),a.blocks.push(this.finishNode(c,"ComprehensionBlock"))}return a.filter=this.eat(d._if)?this.parseParenExpression():null,a.body=this.parseExpression(),this.expect(b?d.parenR:d.bracketR),a.generator=b,this.finishNode(a,"ComprehensionExpression")}},{"./identifier":7,"./state":13,"./tokentype":17,"./util":18}],7:[function(a,b,c){"use strict";function d(a){function b(a){if(1==a.length)return c+="return str === "+JSON.stringify(a[0])+";";c+="switch(str){";for(var b=0;b3){d.sort(function(a,b){return b.length-a.length}),c+="switch(str.length){";for(var e=0;ea)return!1;if(c+=b[d+1],c>=a)return!0}}function f(a,b){return 65>a?36===a:91>a?!0:97>a?95===a:123>a?!0:65535>=a?a>=170&&m.test(String.fromCharCode(a)):b===!1?!1:e(a,o)}function g(a,b){return 48>a?36===a:58>a?!0:65>a?!1:91>a?!0:97>a?95===a:123>a?!0:65535>=a?a>=170&&n.test(String.fromCharCode(a)):b===!1?!1:e(a,o)||e(a,p)}c.isIdentifierStart=f,c.isIdentifierChar=g,c.__esModule=!0;var h={3:d("abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile"),5:d("class enum extends super const export import"),6:d("enum await"),strict:d("implements interface let package private protected public static yield"),strictBind:d("eval arguments")};c.reservedWords=h;var i="break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this",j={5:d(i),6:d(i+" let const class extends export import yield super")};c.keywords=j;var k="ªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙա-ևא-תװ-ײؠ-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺࠀ-ࠕࠚࠤࠨࡀ-ࡘࢠ-ࢲऄ-हऽॐक़-ॡॱ-ঀঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡೱೲഅ-ഌഎ-ഐഒ-ഺഽൎൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜ-ໟༀཀ-ཇཉ-ཬྈ-ྌက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᢰ-ᣵᤀ-ᤞᥐ-ᥭᥰ-ᥴᦀ-ᦫᧁ-ᧇᨀ-ᨖᨠ-ᩔᪧᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᮺ-ᯥᰀ-ᰣᱍ-ᱏᱚ-ᱽᳩ-ᳬᳮ-ᳱᳵᳶᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕ℘-ℝℤΩℨK-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞ々-〇〡-〩〱-〵〸-〼ぁ-ゖ゛-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿌ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙿ-ꚝꚠ-ꛯꜗ-ꜟꜢ-ꞈꞋ-ꞎꞐ-ꞭꞰꞱꟷ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꣲ-ꣷꣻꤊ-ꤥꤰ-ꥆꥠ-ꥼꦄ-ꦲꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨨꩀ-ꩂꩄ-ꩋꩠ-ꩶꩺꩾ-ꪯꪱꪵꪶꪹ-ꪽꫀꫂꫛ-ꫝꫠ-ꫪꫲ-ꫴꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭟꭤꭥꯀ-ꯢ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ",l="‌‍·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-٩ٰۖ-ۜ۟-۪ۤۧۨ-ۭ۰-۹ܑܰ-݊ަ-ް߀-߉߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛ࣤ-ःऺ-़ा-ॏ॑-ॗॢॣ०-९ঁ-ঃ়া-ৄেৈো-্ৗৢৣ০-৯ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑ੦-ੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣ૦-૯ଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣ୦-୯ஂா-ூெ-ைொ-்ௗ௦-௯ఀ-ఃా-ౄె-ైొ-్ౕౖౢౣ౦-౯ಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣ೦-೯ഁ-ഃാ-ൄെ-ൈൊ-്ൗൢൣ൦-൯ංඃ්ා-ුූෘ-ෟ෦-෯ෲෳัิ-ฺ็-๎๐-๙ັິ-ູົຼ່-ໍ໐-໙༘༙༠-༩༹༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှ၀-၉ၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏ-ႝ፝-፟፩-፱ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝០-៩᠋-᠍᠐-᠙ᢩᤠ-ᤫᤰ-᤻᥆-᥏ᦰ-ᧀᧈᧉ᧐-᧚ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼-᪉᪐-᪙᪰-᪽ᬀ-ᬄ᬴-᭄᭐-᭙᭫-᭳ᮀ-ᮂᮡ-ᮭ᮰-᮹᯦-᯳ᰤ-᰷᱀-᱉᱐-᱙᳐-᳔᳒-᳨᳭ᳲ-᳴᳸᳹᷀-᷵᷼-᷿‿⁀⁔⃐-⃥⃜⃡-⃰⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꘠-꘩꙯ꙴ-꙽ꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-꣄꣐-꣙꣠-꣱꤀-꤉ꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀꧐-꧙ꧥ꧰-꧹ꨩ-ꨶꩃꩌꩍ꩐-꩙ꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭꯰-꯹ﬞ︀-️︠-︭︳︴﹍-﹏0-9_",m=new RegExp("["+k+"]"),n=new RegExp("["+k+l+"]");k=l=null;var o=[0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,17,26,6,37,11,29,3,35,5,7,2,4,43,157,99,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,98,21,11,25,71,55,7,1,65,0,16,3,2,2,2,26,45,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,955,52,76,44,33,24,27,35,42,34,4,0,13,47,15,3,22,0,38,17,2,24,133,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,32,4,287,47,21,1,2,0,185,46,82,47,21,0,60,42,502,63,32,0,449,56,1288,920,104,110,2962,1070,13266,568,8,30,114,29,19,47,17,3,32,20,6,18,881,68,12,0,67,12,16481,1,3071,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,4149,196,1340,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42710,42,4148,12,221,16355,541],p=[509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,1306,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,52,0,13,2,49,13,16,9,83,11,168,11,6,9,8,2,57,0,2,6,3,1,3,2,10,0,11,1,3,6,4,4,316,19,13,9,214,6,3,8,112,16,16,9,82,12,9,9,535,9,20855,9,135,4,60,6,26,9,1016,45,17,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,4305,6,792618,239]},{}],8:[function(a,b,c){"use strict";function d(a,b){for(var c=1,d=0;;){g.lastIndex=d;var e=g.exec(a);if(!(e&&e.index=6&&a)switch(a.type){case"Identifier":case"ObjectPattern":case"ArrayPattern":case"AssignmentPattern":break;case"ObjectExpression":a.type="ObjectPattern";for(var c=0;c=6&&(a.sourceType=this.options.sourceType),this.finishNode(a,"Program")};var h={kind:"loop"},i={kind:"switch"};g.parseStatement=function(a,b){var c=this.type,e=this.startNode();switch(c){case d._break:case d._continue:return this.parseBreakContinueStatement(e,c.keyword);case d._debugger:return this.parseDebuggerStatement(e);case d._do:return this.parseDoStatement(e);case d._for:return this.parseForStatement(e);case d._function:return!a&&this.options.ecmaVersion>=6&&this.unexpected(),this.parseFunctionStatement(e);case d._class:return a||this.unexpected(),this.parseClass(e,!0);case d._if:return this.parseIfStatement(e);case d._return:return this.parseReturnStatement(e);case d._switch:return this.parseSwitchStatement(e);case d._throw:return this.parseThrowStatement(e);case d._try:return this.parseTryStatement(e);case d._let:case d._const:a||this.unexpected();case d._var:return this.parseVarStatement(e,c);case d._while:return this.parseWhileStatement(e);case d._with:return this.parseWithStatement(e);case d.braceL:return this.parseBlock();case d.semi:return this.parseEmptyStatement(e);case d._export:case d._import:return this.options.allowImportExportEverywhere||(b||this.raise(this.start,"'import' and 'export' may only appear at the top level"),this.inModule||this.raise(this.start,"'import' and 'export' may appear only with 'sourceType: module'")),c===d._import?this.parseImport(e):this.parseExport(e);default:var f=this.value,g=this.parseExpression();return c===d.name&&"Identifier"===g.type&&this.eat(d.colon)?this.parseLabeledStatement(e,f,g):this.parseExpressionStatement(e,g)}},g.parseBreakContinueStatement=function(a,b){var c="break"==b;this.next(),this.eat(d.semi)||this.insertSemicolon()?a.label=null:this.type!==d.name?this.unexpected():(a.label=this.parseIdent(),this.semicolon());for(var e=0;e=6?this.eat(d.semi):this.semicolon(),this.finishNode(a,"DoWhileStatement")},g.parseForStatement=function(a){if(this.next(),this.labels.push(h),this.expect(d.parenL),this.type===d.semi)return this.parseFor(a,null);if(this.type===d._var||this.type===d._let||this.type===d._const){var b=this.startNode(),c=this.type;return this.next(),this.parseVar(b,!0,c),this.finishNode(b,"VariableDeclaration"),!(this.type===d._in||this.options.ecmaVersion>=6&&this.isContextual("of"))||1!==b.declarations.length||c!==d._var&&b.declarations[0].init?this.parseFor(a,b):this.parseForIn(a,b)}var e={start:0},f=this.parseExpression(!0,e);return this.type===d._in||this.options.ecmaVersion>=6&&this.isContextual("of")?(this.toAssignable(f), +this.checkLVal(f),this.parseForIn(a,f)):(e.start&&this.unexpected(e.start),this.parseFor(a,f))},g.parseFunctionStatement=function(a){return this.next(),this.parseFunction(a,!0)},g.parseIfStatement=function(a){return this.next(),a.test=this.parseParenExpression(),a.consequent=this.parseStatement(!1),a.alternate=this.eat(d._else)?this.parseStatement(!1):null,this.finishNode(a,"IfStatement")},g.parseReturnStatement=function(a){return this.inFunction||this.options.allowReturnOutsideFunction||this.raise(this.start,"'return' outside of function"),this.next(),this.eat(d.semi)||this.insertSemicolon()?a.argument=null:(a.argument=this.parseExpression(),this.semicolon()),this.finishNode(a,"ReturnStatement")},g.parseSwitchStatement=function(a){this.next(),a.discriminant=this.parseParenExpression(),a.cases=[],this.expect(d.braceL),this.labels.push(i);for(var b,c;this.type!=d.braceR;)if(this.type===d._case||this.type===d._default){var e=this.type===d._case;b&&this.finishNode(b,"SwitchCase"),a.cases.push(b=this.startNode()),b.consequent=[],this.next(),e?b.test=this.parseExpression():(c&&this.raise(this.lastTokStart,"Multiple default clauses"),c=!0,b.test=null),this.expect(d.colon)}else b||this.unexpected(),b.consequent.push(this.parseStatement(!0));return b&&this.finishNode(b,"SwitchCase"),this.next(),this.labels.pop(),this.finishNode(a,"SwitchStatement")},g.parseThrowStatement=function(a){return this.next(),f.test(this.input.slice(this.lastTokEnd,this.start))&&this.raise(this.lastTokEnd,"Illegal newline after throw"),a.argument=this.parseExpression(),this.semicolon(),this.finishNode(a,"ThrowStatement")};var j=[];g.parseTryStatement=function(a){if(this.next(),a.block=this.parseBlock(),a.handler=null,this.type===d._catch){var b=this.startNode();this.next(),this.expect(d.parenL),b.param=this.parseBindingAtom(),this.checkLVal(b.param,!0),this.expect(d.parenR),b.guard=null,b.body=this.parseBlock(),a.handler=this.finishNode(b,"CatchClause")}return a.guardedHandlers=j,a.finalizer=this.eat(d._finally)?this.parseBlock():null,a.handler||a.finalizer||this.raise(a.start,"Missing catch or finally clause"),this.finishNode(a,"TryStatement")},g.parseVarStatement=function(a,b){return this.next(),this.parseVar(a,!1,b),this.semicolon(),this.finishNode(a,"VariableDeclaration")},g.parseWhileStatement=function(a){return this.next(),a.test=this.parseParenExpression(),this.labels.push(h),a.body=this.parseStatement(!1),this.labels.pop(),this.finishNode(a,"WhileStatement")},g.parseWithStatement=function(a){return this.strict&&this.raise(this.start,"'with' in strict mode"),this.next(),a.object=this.parseParenExpression(),a.body=this.parseStatement(!1),this.finishNode(a,"WithStatement")},g.parseEmptyStatement=function(a){return this.next(),this.finishNode(a,"EmptyStatement")},g.parseLabeledStatement=function(a,b,c){for(var e=0;e=6&&this.isContextual("of")?"Identifier"==e.id.type||b&&(this.type===d._in||this.isContextual("of"))?e.init=null:this.raise(this.lastTokEnd,"Complex binding patterns require an initialization value"):this.unexpected(),a.declarations.push(this.finishNode(e,"VariableDeclarator")),!this.eat(d.comma))break}return a},g.parseVarId=function(a){a.id=this.parseBindingAtom(),this.checkLVal(a.id,!0)},g.parseFunction=function(a,b,c){return this.initFunction(a),this.options.ecmaVersion>=6&&(a.generator=this.eat(d.star)),(b||this.type===d.name)&&(a.id=this.parseIdent()),this.parseFunctionParams(a),this.parseFunctionBody(a,c),this.finishNode(a,b?"FunctionDeclaration":"FunctionExpression")},g.parseFunctionParams=function(a){this.expect(d.parenL),a.params=this.parseBindingList(d.parenR,!1,!1)},g.parseClass=function(a,b){this.next(),this.parseClassId(a,b),this.parseClassSuper(a);var c=this.startNode(),e=!1;for(c.body=[],this.expect(d.braceL);!this.eat(d.braceR);)if(!this.eat(d.semi)){var f=this.startNode(),g=this.eat(d.star),h=this.type===d.name&&"static"===this.value;if(this.parsePropertyName(f),f["static"]=h&&this.type!==d.parenL,f["static"]&&(g&&this.unexpected(),g=this.eat(d.star),this.parsePropertyName(f)),f.kind="method",!f.computed){var i=f.key,j=!1;g||"Identifier"!==i.type||this.type===d.parenL||"get"!==i.name&&"set"!==i.name||(j=!0,f.kind=i.name,i=this.parsePropertyName(f)),!f["static"]&&("Identifier"===i.type&&"constructor"===i.name||"Literal"===i.type&&"constructor"===i.value)&&(e&&this.raise(i.start,"Duplicate constructor in the same class"),j&&this.raise(i.start,"Constructor can't have get/set modifier"),g&&this.raise(i.start,"Constructor can't be a generator"),f.kind="constructor",e=!0)}this.parseClassMethod(c,f,g)}return a.body=this.finishNode(c,"ClassBody"),this.finishNode(a,b?"ClassDeclaration":"ClassExpression")},g.parseClassMethod=function(a,b,c){b.value=this.parseMethod(c),a.body.push(this.finishNode(b,"MethodDefinition"))},g.parseClassId=function(a,b){a.id=this.type===d.name?this.parseIdent():b?this.unexpected():null},g.parseClassSuper=function(a){a.superClass=this.eat(d._extends)?this.parseExprSubscripts():null},g.parseExport=function(a){if(this.next(),this.eat(d.star))return this.expectContextual("from"),a.source=this.type===d.string?this.parseExprAtom():this.unexpected(),this.semicolon(),this.finishNode(a,"ExportAllDeclaration");if(this.eat(d._default)){var b=this.parseMaybeAssign(),c=!0;return("FunctionExpression"==b.type||"ClassExpression"==b.type)&&(c=!1,b.id&&(b.type="FunctionExpression"==b.type?"FunctionDeclaration":"ClassDeclaration")),a.declaration=b,c&&this.semicolon(),this.finishNode(a,"ExportDefaultDeclaration")}return this.shouldParseExportStatement()?(a.declaration=this.parseStatement(!0),a.specifiers=[],a.source=null):(a.declaration=null,a.specifiers=this.parseExportSpecifiers(),this.eatContextual("from")?a.source=this.type===d.string?this.parseExprAtom():this.unexpected():a.source=null,this.semicolon()),this.finishNode(a,"ExportNamedDeclaration")},g.shouldParseExportStatement=function(){return this.type.keyword},g.parseExportSpecifiers=function(){var a=[],b=!0;for(this.expect(d.braceL);!this.eat(d.braceR);){if(b)b=!1;else if(this.expect(d.comma),this.afterTrailingComma(d.braceR))break;var c=this.startNode();c.local=this.parseIdent(this.type===d._default),c.exported=this.eatContextual("as")?this.parseIdent(!0):c.local,a.push(this.finishNode(c,"ExportSpecifier"))}return a},g.parseImport=function(a){return this.next(),this.type===d.string?(a.specifiers=j,a.source=this.parseExprAtom(),a.kind=""):(a.specifiers=this.parseImportSpecifiers(),this.expectContextual("from"),a.source=this.type===d.string?this.parseExprAtom():this.unexpected()),this.semicolon(),this.finishNode(a,"ImportDeclaration")},g.parseImportSpecifiers=function(){var a=[],b=!0;if(this.type===d.name){var c=this.startNode();if(c.local=this.parseIdent(),this.checkLVal(c.local,!0),a.push(this.finishNode(c,"ImportDefaultSpecifier")),!this.eat(d.comma))return a}if(this.type===d.star){var c=this.startNode();return this.next(),this.expectContextual("as"),c.local=this.parseIdent(),this.checkLVal(c.local,!0),a.push(this.finishNode(c,"ImportNamespaceSpecifier")),a}for(this.expect(d.braceL);!this.eat(d.braceR);){if(b)b=!1;else if(this.expect(d.comma),this.afterTrailingComma(d.braceR))break;var c=this.startNode();c.imported=this.parseIdent(!0),c.local=this.eatContextual("as")?this.parseIdent():c.imported,this.checkLVal(c.local,!0),a.push(this.finishNode(c,"ImportSpecifier"))}return a}},{"./state":13,"./tokentype":17,"./whitespace":19}],15:[function(a,b,c){"use strict";var d=function(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")};c.__esModule=!0;var e=a("./state").Parser,f=a("./tokentype").types,g=a("./whitespace").lineBreak,h=c.TokContext=function k(a,b,c,e){d(this,k),this.token=a,this.isExpr=b,this.preserveSpace=c,this.override=e},i={b_stat:new h("{",!1),b_expr:new h("{",!0),b_tmpl:new h("${",!0),p_stat:new h("(",!1),p_expr:new h("(",!0),q_tmpl:new h("`",!0,!0,function(a){return a.readTmplToken()}),f_expr:new h("function",!0)};c.types=i;var j=e.prototype;j.initialContext=function(){return[i.b_stat]},j.braceIsBlock=function(a){var b=void 0;return a===f.colon&&"{"==(b=this.curContext()).token?!b.isExpr:a===f._return?g.test(this.input.slice(this.lastTokEnd,this.start)):a===f._else||a===f.semi||a===f.eof?!0:a==f.braceL?this.curContext()===i.b_stat:!this.exprAllowed},j.updateContext=function(a){var b=void 0,c=this.type;c.keyword&&a==f.dot?this.exprAllowed=!1:(b=c.updateContext)?b.call(this,a):this.exprAllowed=c.beforeExpr},f.parenR.updateContext=f.braceR.updateContext=function(){if(1==this.context.length)return void(this.exprAllowed=!0);var a=this.context.pop();a===i.b_stat&&this.curContext()===i.f_expr?(this.context.pop(),this.exprAllowed=!1):a===i.b_tmpl?this.exprAllowed=!0:this.exprAllowed=!a.isExpr},f.braceL.updateContext=function(a){this.context.push(this.braceIsBlock(a)?i.b_stat:i.b_expr),this.exprAllowed=!0},f.dollarBraceL.updateContext=function(){this.context.push(i.b_tmpl),this.exprAllowed=!0},f.parenL.updateContext=function(a){var b=a===f._if||a===f._for||a===f._with||a===f._while;this.context.push(b?i.p_stat:i.p_expr),this.exprAllowed=!0},f.incDec.updateContext=function(){},f._function.updateContext=function(){this.curContext()!==i.b_stat&&this.context.push(i.f_expr),this.exprAllowed=!1},f.backQuote.updateContext=function(){this.curContext()===i.q_tmpl?this.context.pop():this.context.push(i.q_tmpl),this.exprAllowed=!1}},{"./state":13,"./tokentype":17,"./whitespace":19}],16:[function(a,b,c){"use strict";function d(a){return 65535>=a?String.fromCharCode(a):String.fromCharCode((a-65536>>10)+55296,(a-65536&1023)+56320)}var e=function(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")};c.__esModule=!0;var f=a("./identifier"),g=f.isIdentifierStart,h=f.isIdentifierChar,i=a("./tokentype"),j=i.types,k=i.keywords,l=a("./state").Parser,m=a("./location").SourceLocation,n=a("./whitespace"),o=n.lineBreak,p=n.lineBreakG,q=n.isNewLine,r=n.nonASCIIwhitespace,s=c.Token=function y(a){e(this,y),this.type=a.type,this.value=a.value,this.start=a.start,this.end=a.end,a.options.locations&&(this.loc=new m(a,a.startLoc,a.endLoc)),a.options.ranges&&(this.range=[a.start,a.end])},t=l.prototype,u="undefined"!=typeof Packages;t.next=function(){this.options.onToken&&this.options.onToken(new s(this)),this.lastTokEnd=this.end,this.lastTokStart=this.start,this.lastTokEndLoc=this.endLoc,this.lastTokStartLoc=this.startLoc,this.nextToken()},t.getToken=function(){return this.next(),new s(this)},"undefined"!=typeof Symbol&&(t[Symbol.iterator]=function(){var a=this;return{next:function(){var b=a.getToken();return{done:b.type===j.eof,value:b}}}}),t.setStrict=function(a){if(this.strict=a,this.type===j.num||this.type===j.string){if(this.pos=this.start,this.options.locations)for(;this.pos=this.input.length?this.finishToken(j.eof):a.override?a.override(this):void this.readToken(this.fullCharCodeAtPos())},t.readToken=function(a){return g(a,this.options.ecmaVersion>=6)||92===a?this.readWord():this.getTokenFromCode(a)},t.fullCharCodeAtPos=function(){var a=this.input.charCodeAt(this.pos);if(55295>=a||a>=57344)return a;var b=this.input.charCodeAt(this.pos+1);return(a<<10)+b-56613888},t.skipBlockComment=function(){var a=this.options.onComment&&this.options.locations&&this.curPosition(),b=this.pos,c=this.input.indexOf("*/",this.pos+=2);if(-1===c&&this.raise(this.pos-2,"Unterminated comment"),this.pos=c+2,this.options.locations){p.lastIndex=b;for(var d=void 0;(d=p.exec(this.input))&&d.index8&&14>a)++this.pos;else if(47===a){var b=this.input.charCodeAt(this.pos+1);if(42===b)this.skipBlockComment();else{if(47!==b)break;this.skipLineComment(2)}}else if(160===a)++this.pos;else{if(!(a>=5760&&r.test(String.fromCharCode(a))))break;++this.pos}}},t.finishToken=function(a,b){this.end=this.pos,this.options.locations&&(this.endLoc=this.curPosition());var c=this.type;this.type=a,this.value=b,this.updateContext(c)},t.readToken_dot=function(){var a=this.input.charCodeAt(this.pos+1);if(a>=48&&57>=a)return this.readNumber(!0);var b=this.input.charCodeAt(this.pos+2);return this.options.ecmaVersion>=6&&46===a&&46===b?(this.pos+=3,this.finishToken(j.ellipsis)):(++this.pos,this.finishToken(j.dot))},t.readToken_slash=function(){var a=this.input.charCodeAt(this.pos+1);return this.exprAllowed?(++this.pos,this.readRegexp()):61===a?this.finishOp(j.assign,2):this.finishOp(j.slash,1)},t.readToken_mult_modulo=function(a){var b=this.input.charCodeAt(this.pos+1);return 61===b?this.finishOp(j.assign,2):this.finishOp(42===a?j.star:j.modulo,1)},t.readToken_pipe_amp=function(a){var b=this.input.charCodeAt(this.pos+1);return b===a?this.finishOp(124===a?j.logicalOR:j.logicalAND,2):61===b?this.finishOp(j.assign,2):this.finishOp(124===a?j.bitwiseOR:j.bitwiseAND,1)},t.readToken_caret=function(){var a=this.input.charCodeAt(this.pos+1);return 61===a?this.finishOp(j.assign,2):this.finishOp(j.bitwiseXOR,1)},t.readToken_plus_min=function(a){var b=this.input.charCodeAt(this.pos+1);return b===a?45==b&&62==this.input.charCodeAt(this.pos+2)&&o.test(this.input.slice(this.lastTokEnd,this.pos))?(this.skipLineComment(3),this.skipSpace(),this.nextToken()):this.finishOp(j.incDec,2):61===b?this.finishOp(j.assign,2):this.finishOp(j.plusMin,1)},t.readToken_lt_gt=function(a){var b=this.input.charCodeAt(this.pos+1),c=1;return b===a?(c=62===a&&62===this.input.charCodeAt(this.pos+2)?3:2,61===this.input.charCodeAt(this.pos+c)?this.finishOp(j.assign,c+1):this.finishOp(j.bitShift,c)):33==b&&60==a&&45==this.input.charCodeAt(this.pos+2)&&45==this.input.charCodeAt(this.pos+3)?(this.inModule&&this.unexpected(),this.skipLineComment(4),this.skipSpace(),this.nextToken()):(61===b&&(c=61===this.input.charCodeAt(this.pos+2)?3:2),this.finishOp(j.relational,c))},t.readToken_eq_excl=function(a){var b=this.input.charCodeAt(this.pos+1);return 61===b?this.finishOp(j.equality,61===this.input.charCodeAt(this.pos+2)?3:2):61===a&&62===b&&this.options.ecmaVersion>=6?(this.pos+=2,this.finishToken(j.arrow)):this.finishOp(61===a?j.eq:j.prefix,1)},t.getTokenFromCode=function(a){switch(a){case 46:return this.readToken_dot();case 40:return++this.pos,this.finishToken(j.parenL);case 41:return++this.pos,this.finishToken(j.parenR);case 59:return++this.pos,this.finishToken(j.semi);case 44:return++this.pos,this.finishToken(j.comma);case 91:return++this.pos,this.finishToken(j.bracketL);case 93:return++this.pos,this.finishToken(j.bracketR);case 123:return++this.pos,this.finishToken(j.braceL);case 125:return++this.pos,this.finishToken(j.braceR);case 58:return++this.pos,this.finishToken(j.colon);case 63:return++this.pos,this.finishToken(j.question);case 96:if(this.options.ecmaVersion<6)break;return++this.pos,this.finishToken(j.backQuote);case 48:var b=this.input.charCodeAt(this.pos+1);if(120===b||88===b)return this.readRadixNumber(16);if(this.options.ecmaVersion>=6){if(111===b||79===b)return this.readRadixNumber(8);if(98===b||66===b)return this.readRadixNumber(2)}case 49:case 50:case 51:case 52:case 53:case 54:case 55:case 56:case 57:return this.readNumber(!1);case 34:case 39:return this.readString(a);case 47:return this.readToken_slash();case 37:case 42:return this.readToken_mult_modulo(a);case 124:case 38:return this.readToken_pipe_amp(a);case 94:return this.readToken_caret();case 43:case 45:return this.readToken_plus_min(a);case 60:case 62:return this.readToken_lt_gt(a);case 61:case 33:return this.readToken_eq_excl(a);case 126:return this.finishOp(j.prefix,1)}this.raise(this.pos,"Unexpected character '"+d(a)+"'")},t.finishOp=function(a,b){var c=this.input.slice(this.pos,this.pos+b);return this.pos+=b,this.finishToken(a,c)};var v=!1;try{new RegExp("￿","u"),v=!0}catch(w){}t.readRegexp=function(){for(var a=void 0,b=void 0,c=this.pos;;){this.pos>=this.input.length&&this.raise(c,"Unterminated regular expression");var d=this.input.charAt(this.pos);if(o.test(d)&&this.raise(c,"Unterminated regular expression"),a)a=!1;else{if("["===d)b=!0;else if("]"===d&&b)b=!1;else if("/"===d&&!b)break;a="\\"===d}++this.pos}var e=this.input.slice(c,this.pos);++this.pos;var f=this.readWord1(),g=e;if(f){var h=/^[gmsiy]*$/;this.options.ecmaVersion>=6&&(h=/^[gmsiyu]*$/),h.test(f)||this.raise(c,"Invalid regular expression flag"),f.indexOf("u")>=0&&!v&&(g=g.replace(/\\u([a-fA-F0-9]{4})|\\u\{([0-9a-fA-F]+)\}|[\uD800-\uDBFF][\uDC00-\uDFFF]/g,"x"))}var i=null;if(!u){try{new RegExp(g)}catch(k){k instanceof SyntaxError&&this.raise(c,"Error parsing regular expression: "+k.message),this.raise(k)}try{i=new RegExp(e,f)}catch(l){}}return this.finishToken(j.regexp,{pattern:e,flags:f,value:i})},t.readInt=function(a,b){for(var c=this.pos,d=0,e=0,f=null==b?1/0:b;f>e;++e){var g=this.input.charCodeAt(this.pos),h=void 0;if(h=g>=97?g-97+10:g>=65?g-65+10:g>=48&&57>=g?g-48:1/0,h>=a)break;++this.pos,d=d*a+h}return this.pos===c||null!=b&&this.pos-c!==b?null:d},t.readRadixNumber=function(a){this.pos+=2;var b=this.readInt(a);return null==b&&this.raise(this.start+2,"Expected number in radix "+a),g(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number"),this.finishToken(j.num,b)},t.readNumber=function(a){var b=this.pos,c=!1,d=48===this.input.charCodeAt(this.pos);a||null!==this.readInt(10)||this.raise(b,"Invalid number"),46===this.input.charCodeAt(this.pos)&&(++this.pos,this.readInt(10),c=!0);var e=this.input.charCodeAt(this.pos);(69===e||101===e)&&(e=this.input.charCodeAt(++this.pos),(43===e||45===e)&&++this.pos,null===this.readInt(10)&&this.raise(b,"Invalid number"),c=!0),g(this.fullCharCodeAtPos())&&this.raise(this.pos,"Identifier directly after number");var f=this.input.slice(b,this.pos),h=void 0;return c?h=parseFloat(f):d&&1!==f.length?/[89]/.test(f)||this.strict?this.raise(b,"Invalid number"):h=parseInt(f,8):h=parseInt(f,10),this.finishToken(j.num,h)},t.readCodePoint=function(){var a=this.input.charCodeAt(this.pos),b=void 0;return 123===a?(this.options.ecmaVersion<6&&this.unexpected(),++this.pos,b=this.readHexChar(this.input.indexOf("}",this.pos)-this.pos),++this.pos,b>1114111&&this.unexpected()):b=this.readHexChar(4),b},t.readString=function(a){for(var b="",c=++this.pos;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated string constant");var d=this.input.charCodeAt(this.pos);if(d===a)break;92===d?(b+=this.input.slice(c,this.pos),b+=this.readEscapedChar(),c=this.pos):(q(d)&&this.raise(this.start,"Unterminated string constant"),++this.pos)}return b+=this.input.slice(c,this.pos++),this.finishToken(j.string,b)},t.readTmplToken=function(){for(var a="",b=this.pos;;){this.pos>=this.input.length&&this.raise(this.start,"Unterminated template");var c=this.input.charCodeAt(this.pos);if(96===c||36===c&&123===this.input.charCodeAt(this.pos+1))return this.pos===this.start&&this.type===j.template?36===c?(this.pos+=2,this.finishToken(j.dollarBraceL)):(++this.pos,this.finishToken(j.backQuote)):(a+=this.input.slice(b,this.pos),this.finishToken(j.template,a));92===c?(a+=this.input.slice(b,this.pos),a+=this.readEscapedChar(),b=this.pos):q(c)?(a+=this.input.slice(b,this.pos),++this.pos,13===c&&10===this.input.charCodeAt(this.pos)?(++this.pos,a+="\n"):a+=String.fromCharCode(c),this.options.locations&&(++this.curLine,this.lineStart=this.pos),b=this.pos):++this.pos}},t.readEscapedChar=function(){var a=this.input.charCodeAt(++this.pos),b=/^[0-7]+/.exec(this.input.slice(this.pos,this.pos+3));for(b&&(b=b[0]);b&&parseInt(b,8)>255;)b=b.slice(0,-1);if("0"===b&&(b=null),++this.pos,b)return this.strict&&this.raise(this.pos-2,"Octal literal in strict mode"),this.pos+=b.length-1,String.fromCharCode(parseInt(b,8));switch(a){case 110:return"\n";case 114:return"\r";case 120:return String.fromCharCode(this.readHexChar(2));case 117:return d(this.readCodePoint());case 116:return" ";case 98:return"\b";case 118:return"\x0B";case 102:return"\f";case 48:return"\x00";case 13:10===this.input.charCodeAt(this.pos)&&++this.pos;case 10:return this.options.locations&&(this.lineStart=this.pos,++this.curLine),"";default:return String.fromCharCode(a)}},t.readHexChar=function(a){var b=this.readInt(16,a);return null===b&&this.raise(this.start,"Bad character escape sequence"),b};var x;t.readWord1=function(){x=!1;for(var a="",b=!0,c=this.pos,e=this.options.ecmaVersion>=6;this.pos=f?1:2;else{if(92!==f)break;x=!0,a+=this.input.slice(c,this.pos);var i=this.pos;117!=this.input.charCodeAt(++this.pos)&&this.raise(this.pos,"Expecting Unicode escape sequence \\uXXXX"),++this.pos;var j=this.readCodePoint();(b?g:h)(j,e)||this.raise(i,"Invalid Unicode escape"),a+=d(j),c=this.pos}b=!1}return a+this.input.slice(c,this.pos)},t.readWord=function(){var a=this.readWord1(),b=j.name;return(this.options.ecmaVersion>=6||!x)&&this.isKeyword(a)&&(b=k[a]),this.finishToken(b,a)}},{"./identifier":7,"./location":8,"./state":13,"./tokentype":17,"./whitespace":19}],17:[function(a,b,c){"use strict";function d(a,b){return new g(a,{beforeExpr:!0,binop:b})}function e(a){var b=void 0===arguments[1]?{}:arguments[1];b.keyword=a,k[a]=j["_"+a]=new g(a,b)}var f=function(a,b){if(!(a instanceof b))throw new TypeError("Cannot call a class as a function")};c.__esModule=!0;var g=c.TokenType=function l(a){var b=void 0===arguments[1]?{}:arguments[1];f(this,l),this.label=a,this.keyword=b.keyword,this.beforeExpr=!!b.beforeExpr,this.startsExpr=!!b.startsExpr,this.isLoop=!!b.isLoop,this.isAssign=!!b.isAssign,this.prefix=!!b.prefix,this.postfix=!!b.postfix,this.binop=b.binop||null,this.updateContext=null},h={beforeExpr:!0},i={startsExpr:!0},j={num:new g("num",i),regexp:new g("regexp",i),string:new g("string",i),name:new g("name",i),eof:new g("eof"),bracketL:new g("[",{beforeExpr:!0,startsExpr:!0}),bracketR:new g("]"),braceL:new g("{",{beforeExpr:!0,startsExpr:!0}),braceR:new g("}"),parenL:new g("(",{beforeExpr:!0,startsExpr:!0}),parenR:new g(")"),comma:new g(",",h),semi:new g(";",h),colon:new g(":",h),dot:new g("."),question:new g("?",h),arrow:new g("=>",h),template:new g("template"),ellipsis:new g("...",h),backQuote:new g("`",i),dollarBraceL:new g("${",{beforeExpr:!0,startsExpr:!0}),eq:new g("=",{beforeExpr:!0,isAssign:!0}),assign:new g("_=",{beforeExpr:!0,isAssign:!0}),incDec:new g("++/--",{prefix:!0,postfix:!0,startsExpr:!0}),prefix:new g("prefix",{beforeExpr:!0,prefix:!0,startsExpr:!0}),logicalOR:d("||",1),logicalAND:d("&&",2),bitwiseOR:d("|",3),bitwiseXOR:d("^",4),bitwiseAND:d("&",5),equality:d("==/!=",6),relational:d("",7),bitShift:d("<>",8),plusMin:new g("+/-",{beforeExpr:!0,binop:9,prefix:!0,startsExpr:!0}),modulo:d("%",10),star:d("*",10),slash:d("/",10)};c.types=j;var k={};c.keywords=k,e("break"),e("case",h),e("catch"),e("continue"),e("debugger"),e("default"),e("do",{isLoop:!0}),e("else",h),e("finally"),e("for",{isLoop:!0}),e("function",i),e("if"),e("return",h),e("switch"),e("throw",h),e("try"),e("var"),e("let"),e("const"),e("while",{isLoop:!0}),e("with"),e("new",{beforeExpr:!0,startsExpr:!0}),e("this",i),e("super",i),e("class"),e("extends",h),e("export"),e("import"),e("yield",{beforeExpr:!0,startsExpr:!0}),e("null",i),e("true",i),e("false",i),e("in",{beforeExpr:!0,binop:7}),e("instanceof",{beforeExpr:!0,binop:7}),e("typeof",{beforeExpr:!0,prefix:!0,startsExpr:!0}),e("void",{beforeExpr:!0,prefix:!0,startsExpr:!0}),e("delete",{beforeExpr:!0,prefix:!0,startsExpr:!0})},{}],18:[function(a,b,c){"use strict";function d(a){return"[object Array]"===Object.prototype.toString.call(a)}function e(a,b){return Object.prototype.hasOwnProperty.call(a,b)}c.isArray=d,c.has=e,c.__esModule=!0},{}],19:[function(a,b,c){"use strict";function d(a){return 10===a||13===a||8232===a||8233==a}c.isNewLine=d,c.__esModule=!0;var e=/\r\n?|\n|\u2028|\u2029/;c.lineBreak=e;var f=new RegExp(e.source,"g");c.lineBreakG=f;var g=/[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/;c.nonASCIIwhitespace=g},{}]},{},[1])(1)})}(null),function(a){"use strict";var b=Object.prototype.toString;a.exports=function(a){var c=b.call(a),d="[object Arguments]"===c;return d||(d="[object Array]"!==c&&null!==a&&"object"==typeof a&&"number"==typeof a.length&&a.length>=0&&"[object Function]"===b.call(a.callee)),d},window.isArguments=a.exports}({exports:{}}),function(a){var b=Object.prototype.hasOwnProperty,c=Object.prototype.toString;a.exports=function(a,d,e){if("[object Function]"!==c.call(d))throw new TypeError("iterator must be a function");var f=a.length;if(f===+f)for(var g=0;f>g;g++)d.call(e,a[g],g,a);else for(var h in a)b.call(a,h)&&d.call(e,a[h],h,a)},window.forEach=a.exports}({exports:{}}),function(a){a.exports=Array.isArray||function(a){return"[object Array]"==Object.prototype.toString.call(a)},window.isArray=a.exports}({exports:{}}),function(a,b){"use strict";var c=Object.prototype.hasOwnProperty,d=Object.prototype.toString,e=Array.prototype.slice,f=a("./isArguments"),g=!{toString:null}.propertyIsEnumerable("toString"),h=function(){}.propertyIsEnumerable("prototype"),i=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],j=function(a){var b=a.constructor;return b&&b.prototype===a},k={$console:!0,$frame:!0,$frameElement:!0,$frames:!0,$parent:!0,$self:!0,$webkitIndexedDB:!0,$webkitStorageInfo:!0,$window:!0},l=function(){if("undefined"==typeof window)return!1;for(var a in window)try{if(!k["$"+a]&&c.call(window,a)&&null!==window[a]&&"object"==typeof window[a])try{j(window[a])}catch(b){return!0}}catch(b){return!0}return!1}(),m=function(a){if("undefined"==typeof window||!l)return j(a);try{return j(a)}catch(b){return!1}},n=function(a){var b=null!==a&&"object"==typeof a,e="[object Function]"===d.call(a),j=f(a),k=b&&"[object String]"===d.call(a),l=[];if(!b&&!e&&!j)throw new TypeError("Object.keys called on a non-object");var n=h&&e;if(k&&a.length>0&&!c.call(a,0))for(var o=0;o0)for(var p=0;pparseInt(b,10)}).forEach(function(b){e+=f+"['"+a+"']["+b+"]=0;\n"}),c&&_blanket._branchingArraySetup.sort(function(a,b){return a.line>b.line}).sort(function(a,b){return a.column>b.column}).forEach(function(b){b.file===a&&(e+="if (typeof "+f+"['"+a+"'].branchData["+b.line+"] === 'undefined'){\n",e+=f+"['"+a+"'].branchData["+b.line+"]=[];\n",e+="}",e+=f+"['"+a+"'].branchData["+b.line+"]["+b.column+"] = [];\n",e+=f+"['"+a+"'].branchData["+b.line+"]["+b.column+"].consequent = "+JSON.stringify(b.consequent)+";\n",e+=f+"['"+a+"'].branchData["+b.line+"]["+b.column+"].alternate = "+JSON.stringify(b.alternate)+";\n")}),e+="}"},_blockifyIf:function(a){if(c.indexOf(a.type)>-1){var b=a.consequent||a.body,d=a.alternate;d&&"BlockStatement"!==d.type&&d.update("{\n"+d.source()+"}\n"),b&&"BlockStatement"!==b.type&&b.update("{\n"+b.source()+"}\n")}},_trackBranch:function(a,b){var c=a.loc.start.line,d=a.loc.start.column;_blanket._branchingArraySetup.push({line:c,column:d,file:b,consequent:a.consequent.loc,alternate:a.alternate.loc});var e="_$branchFcn('"+b+"',"+c+","+d+","+a.test.source()+")?"+a.consequent.source()+":"+a.alternate.source();a.update(e)},_addTracking:function(a){var c=_blanket.getCovVar();return function(d){if(_blanket._blockifyIf(d),b.indexOf(d.type)>-1&&"LabeledStatement"!==d.parent.type){if(_blanket._checkDefs(d,a),"VariableDeclaration"===d.type&&("ForStatement"===d.parent.type||"ForInStatement"===d.parent.type))return;if(!d.loc||!d.loc.start)throw new Error("The instrumenter encountered a node with no location: "+Object.keys(d));d.update(c+"['"+a+"']["+d.loc.start.line+"]++;\n"+d.source()),_blanket._trackingArraySetup.push(d.loc.start.line)}else _blanket.options("branchTracking")&&"ConditionalExpression"===d.type?_blanket._trackBranch(d,a):"Literal"===d.type&&"use strict"===d.value&&d.parent&&"ExpressionStatement"===d.parent.type&&d.parent.parent&&"Program"===d.parent.parent.type&&(_blanket._useStrictMode=!0)}},_checkDefs:function(a,b){if(inBrowser){if("VariableDeclaration"===a.type&&a.declarations&&a.declarations.forEach(function(c){if("window"===c.id.name)throw new Error("Instrumentation error, you cannot redefine the 'window' variable in "+b+":"+a.loc.start.line)}),"FunctionDeclaration"===a.type&&a.params&&a.params.forEach(function(c){if("window"===c.name)throw new Error("Instrumentation error, you cannot redefine the 'window' variable in "+b+":"+a.loc.start.line)}),"ExpressionStatement"===a.type&&a.expression&&a.expression.left&&a.expression.left.object&&a.expression.left.property&&a.expression.left.object.name+"."+a.expression.left.property.name===_blanket.getCovVar())throw new Error("Instrumentation error, you cannot redefine the coverage variable in "+b+":"+a.loc.start.line)}else if("ExpressionStatement"===a.type&&a.expression&&a.expression.left&&!a.expression.left.object&&!a.expression.left.property&&a.expression.left.name===_blanket.getCovVar())throw new Error("Instrumentation error, you cannot redefine the coverage variable in "+b+":"+a.loc.start.line)},setupCoverage:function(){e.instrumentation="blanket",e.stats={suites:0,tests:0,passes:0,pending:0,failures:0,start:new Date}},_checkIfSetup:function(){if(!e.stats)throw new Error("You must call blanket.setupCoverage() first.")},onTestStart:function(){_blanket.options("debug")&&console.log("BLANKET-Test event started"),this._checkIfSetup(),e.stats.tests++,e.stats.pending++},onTestDone:function(a,b){this._checkIfSetup(),b===a?e.stats.passes++:e.stats.failures++,e.stats.pending--},onModuleStart:function(){this._checkIfSetup(),e.stats.suites++},onTestsDone:function(){_blanket.options("debug")&&console.log("BLANKET-Test event done"),this._checkIfSetup(),e.stats.end=new Date,inBrowser?this.report(e):(_blanket.options("branchTracking")||delete(inBrowser?window:global)[_blanket.getCovVar()].branchFcn,this.options("reporter").call(this,e))}},_blanket}(),function(a){var b=a.options;a.extend({outstandingRequireFiles:[],options:function(c,d){var e={};if("string"!=typeof c)b(c),e=c;else{if("undefined"==typeof d)return b(c);b(c,d),e[c]=d}e.adapter&&a._loadFile(e.adapter),e.loader&&a._loadFile(e.loader)},requiringFile:function(b,c){"undefined"==typeof b?a.outstandingRequireFiles=[]:"undefined"==typeof c?a.outstandingRequireFiles.push(b):a.outstandingRequireFiles.splice(a.outstandingRequireFiles.indexOf(b),1)},requireFilesLoaded:function(){return 0===a.outstandingRequireFiles.length},showManualLoader:function(){if(!document.getElementById("blanketLoaderDialog")){var a="
";a+=" 
",a+="
",a+="
",a+="Error: Blanket.js encountered a cross origin request error while instrumenting the source files. ",a+="

This is likely caused by the source files being referenced locally (using the file:// protocol). ",a+="

Some solutions include starting Chrome with special flags, running a server locally, or using a browser without these CORS restrictions (Safari).",a+="
","undefined"!=typeof FileReader&&(a+="
Or, try the experimental loader. When prompted, simply click on the directory containing all the source files you want covered.",a+="Start Loader",a+=""),a+="
Close",a+="
",a+="
";var b=".blanketDialogWrapper {";b+="display:block;",b+="position:fixed;",b+="z-index:40001; }",b+=".blanketDialogOverlay {",b+="position:fixed;",b+="width:100%;",b+="height:100%;",b+="background-color:black;",b+="opacity:.5; ",b+="-ms-filter:'progid:DXImageTransform.Microsoft.Alpha(Opacity=50)'; ",b+="filter:alpha(opacity=50); ",b+="z-index:40001; }",b+=".blanketDialogVerticalOffset { ",b+="position:fixed;",b+="top:30%;",b+="width:100%;",b+="z-index:40002; }",b+=".blanketDialogBox { ",b+="width:405px; ",b+="position:relative;",b+="margin:0 auto;",b+="background-color:white;",b+="padding:10px;",b+="border:1px solid black; }";var c=document.createElement("style");c.innerHTML=b,document.head.appendChild(c);var d=document.createElement("div");d.id="blanketLoaderDialog",d.className="blanketDialogWrapper",d.innerHTML=a,document.body.insertBefore(d,document.body.firstChild)}},manualFileLoader:function(a){function b(a){var b=new FileReader;b.onload=g,b.readAsText(a)}var c=Array.prototype.slice;a=c.call(a).filter(function(a){return""!==a.type});var d=a.length-1,e=0,f={};sessionStorage.blanketSessionLoader&&(f=JSON.parse(sessionStorage.blanketSessionLoader));var g=function(c){var g=c.currentTarget.result,h=a[e],i=h.webkitRelativePath&&""!==h.webkitRelativePath?h.webkitRelativePath:h.name;f[i]=g,e++,e===d?(sessionStorage.setItem("blanketSessionLoader",JSON.stringify(f)),document.location.reload()):b(a[e])};b(a[e])},_loadFile:function(b){if("undefined"!=typeof b){var c=new XMLHttpRequest;c.open("GET",b,!1),c.send(),a._addScript(c.responseText)}},_addScript:function(a){var b=document.createElement("script");b.type="text/javascript",b.text=a,(document.body||document.getElementsByTagName("head")[0]).appendChild(b)},hasAdapter:function(b){return null!==a.options("adapter")},report:function(b){document.getElementById("blanketLoaderDialog")||(a.blanketSession=null),b.files=window._$blanket;blanket.options("commonJS")?blanket._commonjs.require:window.require;if(!b.files||!Object.keys(b.files).length)return void(a.options("debug")&&console.log("BLANKET-Reporting No files were instrumented."));if("undefined"!=typeof b.files.branchFcn&&delete b.files.branchFcn,"string"==typeof a.options("reporter"))a._loadFile(a.options("reporter")),a.customReporter(b,a.options("reporter_options"));else if("function"==typeof a.options("reporter"))a.options("reporter")(b,a.options("reporter_options"));else{if("function"!=typeof a.defaultReporter)throw new Error("no reporter defined.");a.defaultReporter(b,a.options("reporter_options"))}},_bindStartTestRunner:function(a,b){a?a(b):"complete"===document.readyState?b():window.addEventListener("load",b,!1)},_loadSourceFiles:function(b){blanket.options("commonJS")?blanket._commonjs.require:window.require;a.options("debug")&&console.log("BLANKET-Collecting page scripts");var c=a.utils.collectPageScripts();if(0===c.length)b();else{sessionStorage.blanketSessionLoader&&(a.blanketSession=JSON.parse(sessionStorage.blanketSessionLoader)),c.forEach(function(b,c){a.utils.cache[b]={loaded:!1}});var d=-1;a.utils.loadAll(function(a){return a?"undefined"!=typeof c[d+1]:(d++,d>=c.length?null:c[d])},b)}},beforeStartTestRunner:function(b){b=b||{},b.checkRequirejs="undefined"==typeof b.checkRequirejs?!0:b.checkRequirejs,b.callback=b.callback||function(){},b.coverage="undefined"==typeof b.coverage?!0:b.coverage,b.coverage?a._bindStartTestRunner(b.bindEvent,function(){a._loadSourceFiles(function(){var c=function(){return b.condition?b.condition():a.requireFilesLoaded()},d=function(){if(c()){a.options("debug")&&console.log("BLANKET-All files loaded, init start test runner callback.");var e=a.options("testReadyCallback");e?"function"==typeof e?e(b.callback):"string"==typeof e&&(a._addScript(e),b.callback()):b.callback()}else setTimeout(d,13)};d()})}):b.callback()},utils:{qualifyURL:function(a){var b=document.createElement("a");return b.href=a,b.href}}})}(blanket),blanket.defaultReporter=function(a){function b(a){var b=document.getElementById(a);"block"===b.style.display?b.style.display="none":b.style.display="block"}function c(a){return a.replace(/\&/g,"&").replace(//g,">").replace(/\"/g,""").replace(/\'/g,"'").replace(/`/g,"`").replace(/[$]/g,"$").replace(/&/g,"&")}function d(a,b){var c=b?0:1;return"undefined"==typeof a||null===typeof a||"undefined"==typeof a[c]?!1:a[c].length>0}function e(a,b,f,g,h){var i="",j="";if(q.length>0)if(i+="",q[0][0].end.line===h){if(i+=c(b.slice(0,q[0][0].end.column))+"",b=b.slice(q[0][0].end.column),q.shift(),q.length>0)if(i+="",q[0][0].end.line===h){if(i+=c(b.slice(0,q[0][0].end.column))+"",b=b.slice(q[0][0].end.column),q.shift(),!f)return{src:i+c(b),cols:f}}else{if(!f)return{src:i+c(b)+"",cols:f};j=""}else if(!f)return{src:i+c(b),cols:f}}else{if(!f)return{src:i+c(b)+"",cols:f};j=""}var k=f[a],l=k.consequent;if(l.start.line>h)q.unshift([k.alternate,k]),q.unshift([l,k]),b=c(b);else{var m="";if(i+=c(b.slice(0,l.start.column-g))+m,f.length>a+1&&f[a+1].consequent.start.line===h&&f[a+1].consequent.start.column-g";var o=k.alternate;if(o.start.line>h)i+=c(b.slice(l.end.column-g)),q.unshift([o,k]);else{if(i+=c(b.slice(l.end.column-g,o.start.column-g)),m="",i+=m,f.length>a+1&&f[a+1].consequent.start.line===h&&f[a+1].consequent.start.column-g",i+=c(b.slice(o.end.column-g)),b=i}}return{src:b+j,cols:f}}var f="#blanket-main {margin:2px;background:#EEE;color:#333;clear:both;font-family:'Helvetica Neue Light', 'HelveticaNeue-Light', 'Helvetica Neue', Calibri, Helvetica, Arial, sans-serif; font-size:17px;} #blanket-main a {color:#333;text-decoration:none;} #blanket-main a:hover {text-decoration:underline;} .blanket {margin:0;padding:5px;clear:both;border-bottom: 1px solid #FFFFFF;} .bl-error {color:red;}.bl-success {color:#5E7D00;} .bl-file{width:auto;} .bl-cl{float:left;} .blanket div.rs {margin-left:50px; width:150px; float:right} .bl-nb {padding-right:10px;} #blanket-main a.bl-logo {color: #EB1764;cursor: pointer;font-weight: bold;text-decoration: none} .bl-source{ overflow-x:scroll; background-color: #FFFFFF; border: 1px solid #CBCBCB; color: #363636; margin: 25px 20px; width: 80%;} .bl-source div{white-space: pre;font-family: monospace;} .bl-source > div > span:first-child{background-color: #EAEAEA;color: #949494;display: inline-block;padding: 0 10px;text-align: center;width: 30px;} .bl-source .hit{background-color:#c3e6c7} .bl-source .miss{background-color:#e6c3c7} .bl-source span.branchWarning{color:#000;background-color:yellow;} .bl-source span.branchOkay{color:#000;background-color:transparent;}",g=60,h=document.head,i=0,j=document.body,k=Object.keys(a.files).some(function(b){return"undefined"!=typeof a.files[b].branchData}),l="
results
Coverage (%)
Covered/Total Smts.
"+(k?"
Covered/Total Branches
":"")+"
",m="
{{fileNumber}}.{{file}}
{{percentage}} %
{{numberCovered}}/{{totalSmts}}
"+(k?"
{{passedBranches}}/{{totalBranches}}
":"")+"
";grandTotalTemplate="
{{rowTitle}}
{{percentage}} %
{{numberCovered}}/{{totalSmts}}
"+(k?"
{{passedBranches}}/{{totalBranches}}
":"")+"
";var n=document.createElement("script");n.type="text/javascript",n.text=b.toString().replace("function "+b.name,"function blanket_toggleSource"),j.appendChild(n);var o=function(a,b){return Math.round(a/b*100*100)/100},p=function(a,b,c){var d=document.createElement(a);d.innerHTML=c,b.appendChild(d)},q=[],r=function(a){return"undefined"!=typeof a},s=a.files,t={totalSmts:0,numberOfFilesCovered:0,passedBranches:0,totalBranches:0,moduleTotalStatements:{},moduleTotalCoveredStatements:{},moduleTotalBranches:{},moduleTotalCoveredBranches:{}},u=_blanket.options("modulePattern"),v=u?new RegExp(u):null;for(var w in s)if(s.hasOwnProperty(w)){i++;var x,y=s[w],z=0,A=0,B=[];for(x=0;x0||"undefined"!=typeof y.branchData)if("undefined"!=typeof y.branchData[x+1]){var D=y.branchData[x+1].filter(r),E=0;C=e(E,C,D,0,x+1).src}else C=q.length?e(0,C,null,0,x+1).src:c(C);else C=c(C);var F="";y[x+1]?(A+=1,z+=1,F="hit"):0===y[x+1]&&(z++,F="miss"),B[x+1]="
"+(x+1)+""+C+"
"}t.totalSmts+=z,t.numberOfFilesCovered+=A;var G=0,H=0;if("undefined"!=typeof y.branchData)for(var I=0;I0&&"undefined"!=typeof y.branchData[I][J][1]&&y.branchData[I][J][1].length>0&&H++);if(t.passedBranches+=H,t.totalBranches+=G,v){var K=w.match(v)[1];t.moduleTotalStatements.hasOwnProperty(K)||(t.moduleTotalStatements[K]=0,t.moduleTotalCoveredStatements[K]=0),t.moduleTotalStatements[K]+=z,t.moduleTotalCoveredStatements[K]+=A,t.moduleTotalBranches.hasOwnProperty(K)||(t.moduleTotalBranches[K]=0,t.moduleTotalCoveredBranches[K]=0),t.moduleTotalBranches[K]+=G,t.moduleTotalCoveredBranches[K]+=H}var L=o(A,z),M=m.replace("{{file}}",w).replace("{{percentage}}",L).replace("{{numberCovered}}",A).replace(/\{\{fileNumber\}\}/g,i).replace("{{totalSmts}}",z).replace("{{totalBranches}}",G).replace("{{passedBranches}}",H).replace("{{source}}",B.join(" "));M=g>L?M.replace("{{statusclass}}","bl-error"):M.replace("{{statusclass}}","bl-success"),l+=M}var N=function(a,b,c,d,e){var f=o(b,a),h=g>f?"bl-error":"bl-success",i=e?"Total for module: "+e:"Global total",j=grandTotalTemplate.replace("{{rowTitle}}",i).replace("{{percentage}}",f).replace("{{numberCovered}}",b).replace("{{totalSmts}}",a).replace("{{passedBranches}}",d).replace("{{totalBranches}}",c).replace("{{statusclass}}",h);l+=j};if(v)for(var O in t.moduleTotalStatements)if(t.moduleTotalStatements.hasOwnProperty(O)){var P=t.moduleTotalStatements[O],Q=t.moduleTotalCoveredStatements[O],R=t.moduleTotalBranches[O],S=t.moduleTotalCoveredBranches[O];N(P,Q,R,S,O)}N(t.totalSmts,t.numberOfFilesCovered,t.totalBranches,t.passedBranches,null),l+="
",p("style",h,f),document.getElementById("blanket-main")?document.getElementById("blanket-main").innerHTML=l.slice(23,-6):p("div",j,l)},function(){var a={},b=Array.prototype.slice,c=b.call(document.scripts);b.call(c[c.length-1].attributes).forEach(function(b){if("data-cover-only"===b.nodeName&&(a.filter=b.nodeValue),"data-cover-never"===b.nodeName&&(a.antifilter=b.nodeValue),"data-cover-reporter"===b.nodeName&&(a.reporter=b.nodeValue),"data-cover-adapter"===b.nodeName&&(a.adapter=b.nodeValue),"data-cover-loader"===b.nodeName&&(a.loader=b.nodeValue),"data-cover-timeout"===b.nodeName&&(a.timeout=b.nodeValue),"data-cover-modulepattern"===b.nodeName&&(a.modulePattern=b.nodeValue),"data-cover-reporter-options"===b.nodeName)try{a.reporter_options=JSON.parse(b.nodeValue)}catch(c){if(blanket.options("debug"))throw new Error("Invalid reporter options. Must be a valid stringified JSON object.")}if("data-cover-testReadyCallback"===b.nodeName&&(a.testReadyCallback=b.nodeValue),"data-cover-customVariable"===b.nodeName&&(a.customVariable=b.nodeValue),"data-cover-flags"===b.nodeName){var d=" "+b.nodeValue+" ";d.indexOf(" ignoreError ")>-1&&(a.ignoreScriptError=!0),d.indexOf(" autoStart ")>-1&&(a.autoStart=!0),d.indexOf(" ignoreCors ")>-1&&(a.ignoreCors=!0),d.indexOf(" branchTracking ")>-1&&(a.branchTracking=!0),d.indexOf(" sourceURL ")>-1&&(a.sourceURL=!0),d.indexOf(" debug ")>-1&&(a.debug=!0),d.indexOf(" engineOnly ")>-1&&(a.engineOnly=!0),d.indexOf(" commonJS ")>-1&&(a.commonJS=!0),d.indexOf(" instrumentCache ")>-1&&(a.instrumentCache=!0)}}),blanket.options(a),"undefined"!=typeof requirejs&&blanket.options("existingRequireJS",!0),blanket.options("commonJS")&&(blanket._commonjs={})}(),function(a){a.extend({utils:{normalizeBackslashes:function(a){return a.replace(/\\/g,"/")},matchPatternAttribute:function(b,c){if("string"==typeof c){if(0===c.indexOf("[")){var d=c.slice(1,c.length-1).split(",");return d.some(function(c){return a.utils.matchPatternAttribute(b,a.utils.normalizeBackslashes(c.slice(1,-1)))})}if(0===c.indexOf("//")){var e=c.slice(2,c.lastIndexOf("/")),f=c.slice(c.lastIndexOf("/")+1),g=new RegExp(e,f);return g.test(b)}return 0===c.indexOf("#")?window[c.slice(1)].call(window,b):b.indexOf(a.utils.normalizeBackslashes(c))>-1}return c instanceof Array?c.some(function(c){return a.utils.matchPatternAttribute(b,c)}):c instanceof RegExp?c.test(b):"function"==typeof c?c.call(window,b):void 0},blanketEval:function(b){a._addScript(b)},collectPageScripts:function(){var b=Array.prototype.slice,c=(b.call(document.scripts),[]),d=[],e=a.options("filter");if(null!=e){var f=a.options("antifilter");c=b.call(document.scripts).filter(function(c){return 1===b.call(c.attributes).filter(function(b){return"src"===b.nodeName&&a.utils.matchPatternAttribute(b.nodeValue,e)&&("undefined"==typeof f||!a.utils.matchPatternAttribute(b.nodeValue,f))}).length})}else c=b.call(document.querySelectorAll("script[data-cover]"));return d=c.map(function(c){return a.utils.qualifyURL(b.call(c.attributes).filter(function(a){return"src"===a.nodeName})[0].nodeValue)}),e||a.options("filter","['"+d.join("','")+"']"),d},loadAll:function(b,c,d){var e=b(),f=a.utils.scriptIsLoaded(e,a.utils.ifOrdered,b,c);if(a.utils.cache[e]&&a.utils.cache[e].loaded)f();else{var g=function(){a.options("debug")&&console.log("BLANKET-Mark script:"+e+", as loaded and move to next script."),f()},h=function(b){a.options("debug")&&console.log("BLANKET-File loading finished"),"undefined"!=typeof b&&(a.options("debug")&&console.log("BLANKET-Add file to DOM."),a._addScript(b)),g()};a.utils.attachScript({url:e},function(b){a.utils.processFile(b,e,h,h)})}},attachScript:function(b,c){var d=a.options("timeout")||3e3;setTimeout(function(){if(!a.utils.cache[b.url].loaded)throw new Error("error (timeout="+d+") loading source script: "+b.url)},d),a.utils.getFile(b.url,c,function(){throw new Error("error loading source script: "+b.url)})},ifOrdered:function(b,c){var d=b(!0);d?a.utils.loadAll(b,c):c(new Error("Error in loading chain."))},scriptIsLoaded:function(b,c,d,e){return a.options("debug")&&console.log("BLANKET-Returning function"),function(){a.options("debug")&&console.log("BLANKET-Marking file as loaded: "+b),a.utils.cache[b].loaded=!0,a.utils.allLoaded()?(a.options("debug")&&console.log("BLANKET-All files loaded"),e()):c&&(a.options("debug")&&console.log("BLANKET-Load next file."),c(d,e))}},cache:{},allLoaded:function(){for(var b=Object.keys(a.utils.cache),c=0;cb;b+=1){c=progIds[b];try{new ActiveXObject(c);break}catch(d){}}this.createXhr=function(){return new a(c)}}},craeteXhr:function(){throw new Error("cacheXhrConstructor is supposed to overwrite this function.")},getFile:function(b,c,d,e){var f=!1;if(a.blanketSession)for(var g=Object.keys(a.blanketSession),h=0;h-1)return c(a.blanketSession[i]),void(f=!0)}if(!f){var j=a.utils.createXhr();j.open("GET",b,!0),e&&e(j,b),j.onreadystatechange=function(a){var e,f;4===j.readyState&&(e=j.status,e>399&&600>e?(f=new Error(b+" HTTP status: "+e),f.xhr=j,d(f)):c(j.responseText))};try{j.send(null)}catch(k){if(!k.code||101!==k.code&&1012!==k.code||a.options("ignoreCors")!==!1)throw k;a.showManualLoader()}}}}}),function(){var b=(blanket.options("commonJS")?blanket._commonjs.require:window.require,blanket.options("commonJS")?blanket._commonjs.requirejs:window.requirejs);!a.options("engineOnly")&&a.options("existingRequireJS")&&(a.utils.oldloader=b.load,b.load=function(b,c,d){a.requiringFile(d),a.utils.getFile(d,function(e){a.utils.processFile(e,d,function(){b.completeLoad(c)},function(){a.utils.oldloader(b,c,d)})},function(b){throw a.requiringFile(),b})}),a.utils.cacheXhrConstructor()}()}(blanket),function(){if(!mocha)throw new Exception("mocha library does not exist in global namespace!");var a=mocha._reporter,b=function(b){b.on("start",function(){blanket.setupCoverage()}),b.on("end",function(){blanket.onTestsDone()}),b.on("suite",function(){blanket.onModuleStart()}),b.on("test",function(){blanket.onTestStart()}),b.on("test end",function(a){blanket.onTestDone(a.parent.tests.length,"passed"===a.state)}),b.on("hook",function(){blanket.onTestStart()}),b.on("hook end",function(){blanket.onTestsDone()}),new a(b)};b.prototype=a.prototype,mocha.reporter(b);var c=mocha.run,d=null;mocha.run=function(a){d=a,console.log("waiting for blanket...")},blanket.beforeStartTestRunner({callback:function(){blanket.options("existingRequireJS")||c(d),mocha.run=c}})}(); \ No newline at end of file diff --git a/test/libs/mocha-blanket-adapter.js b/test/libs/mocha-blanket-adapter.js new file mode 100644 index 0000000..1868b96 --- /dev/null +++ b/test/libs/mocha-blanket-adapter.js @@ -0,0 +1,78 @@ +(function() { + + if(!mocha) { + throw new Exception("mocha library does not exist in global namespace!"); + } + + + /* + * Mocha Events: + * + * - `start` execution started + * - `end` execution complete + * - `suite` (suite) test suite execution started + * - `suite end` (suite) all tests (and sub-suites) have finished + * - `test` (test) test execution started + * - `test end` (test) test completed + * - `hook` (hook) hook execution started + * - `hook end` (hook) hook complete + * - `pass` (test) test passed + * - `fail` (test, err) test failed + * + */ + + var OriginalReporter = mocha._reporter; + + var BlanketReporter = function(runner) { + runner.on('start', function() { + blanket.setupCoverage(); + }); + + runner.on('end', function() { + blanket.onTestsDone(); + }); + + runner.on('suite', function() { + blanket.onModuleStart(); + }); + + runner.on('test', function() { + blanket.onTestStart(); + }); + + runner.on('test end', function(test) { + blanket.onTestDone(test.parent.tests.length, test.state === 'passed'); + }); + + runner.on('hook', function(){ + blanket.onTestStart(); + }); + + runner.on('hook end', function(){ + blanket.onTestsDone(); + }); + + // NOTE: this is an instance of BlanketReporter + new OriginalReporter(runner); + }; + + BlanketReporter.prototype = OriginalReporter.prototype; + + mocha.reporter(BlanketReporter); + + var oldRun = mocha.run, + oldCallback = null; + + mocha.run = function (finishCallback) { + oldCallback = finishCallback; + console.log("waiting for blanket..."); + }; + blanket.beforeStartTestRunner({ + callback: function(){ + if (!blanket.options("existingRequireJS")){ + oldRun(oldCallback); + } + mocha.run = oldRun; + } + }); +})(); diff --git a/test/libs/require.js b/test/libs/require.js new file mode 100644 index 0000000..693164a --- /dev/null +++ b/test/libs/require.js @@ -0,0 +1,36 @@ +/* + RequireJS 2.1.20 Copyright (c) 2010-2015, The Dojo Foundation All Rights Reserved. + Available via the MIT or new BSD license. + see: http://github.com/jrburke/requirejs for details +*/ +var requirejs,require,define; +(function(ba){function G(b){return"[object Function]"===K.call(b)}function H(b){return"[object Array]"===K.call(b)}function v(b,c){if(b){var d;for(d=0;dthis.depCount&&!this.defined){if(G(l)){if(this.events.error&&this.map.isDefine||e.onError!==ca)try{f=h.execCb(c,l,b,f)}catch(d){a=d}else f=h.execCb(c,l,b,f);this.map.isDefine&& +void 0===f&&((b=this.module)?f=b.exports:this.usingExports&&(f=this.exports));if(a)return a.requireMap=this.map,a.requireModules=this.map.isDefine?[this.map.id]:null,a.requireType=this.map.isDefine?"define":"require",w(this.error=a)}else f=l;this.exports=f;if(this.map.isDefine&&!this.ignore&&(q[c]=f,e.onResourceLoad))e.onResourceLoad(h,this.map,this.depMaps);y(c);this.defined=!0}this.defining=!1;this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete= +!0)}}else t(h.defQueueMap,c)||this.fetch()}},callPlugin:function(){var a=this.map,b=a.id,d=i(a.prefix);this.depMaps.push(d);s(d,"defined",u(this,function(f){var l,d;d=n(aa,this.map.id);var g=this.map.name,P=this.map.parentMap?this.map.parentMap.name:null,p=h.makeRequire(a.parentMap,{enableBuildCallback:!0});if(this.map.unnormalized){if(f.normalize&&(g=f.normalize(g,function(a){return c(a,P,!0)})||""),f=i(a.prefix+"!"+g,this.map.parentMap),s(f,"defined",u(this,function(a){this.init([],function(){return a}, +null,{enabled:!0,ignore:!0})})),d=n(m,f.id)){this.depMaps.push(f);if(this.events.error)d.on("error",u(this,function(a){this.emit("error",a)}));d.enable()}}else d?(this.map.url=h.nameToUrl(d),this.load()):(l=u(this,function(a){this.init([],function(){return a},null,{enabled:!0})}),l.error=u(this,function(a){this.inited=!0;this.error=a;a.requireModules=[b];A(m,function(a){0===a.map.id.indexOf(b+"_unnormalized")&&y(a.map.id)});w(a)}),l.fromText=u(this,function(f,c){var d=a.name,g=i(d),P=M;c&&(f=c);P&& +(M=!1);r(g);t(k.config,b)&&(k.config[d]=k.config[b]);try{e.exec(f)}catch(m){return w(B("fromtexteval","fromText eval for "+b+" failed: "+m,m,[b]))}P&&(M=!0);this.depMaps.push(g);h.completeLoad(d);p([d],l)}),f.load(a.name,p,l,k))}));h.enable(d,this);this.pluginMaps[d.id]=d},enable:function(){V[this.map.id]=this;this.enabling=this.enabled=!0;v(this.depMaps,u(this,function(a,b){var c,f;if("string"===typeof a){a=i(a,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap);this.depMaps[b]=a;if(c= +n(L,a.id)){this.depExports[b]=c(this);return}this.depCount+=1;s(a,"defined",u(this,function(a){this.undefed||(this.defineDep(b,a),this.check())}));this.errback?s(a,"error",u(this,this.errback)):this.events.error&&s(a,"error",u(this,function(a){this.emit("error",a)}))}c=a.id;f=m[c];!t(L,c)&&(f&&!f.enabled)&&h.enable(a,this)}));A(this.pluginMaps,u(this,function(a){var b=n(m,a.id);b&&!b.enabled&&h.enable(a,this)}));this.enabling=!1;this.check()},on:function(a,b){var c=this.events[a];c||(c=this.events[a]= +[]);c.push(b)},emit:function(a,b){v(this.events[a],function(a){a(b)});"error"===a&&delete this.events[a]}};h={config:k,contextName:b,registry:m,defined:q,urlFetched:S,defQueue:C,defQueueMap:{},Module:Z,makeModuleMap:i,nextTick:e.nextTick,onError:w,configure:function(a){a.baseUrl&&"/"!==a.baseUrl.charAt(a.baseUrl.length-1)&&(a.baseUrl+="/");var b=k.shim,c={paths:!0,bundles:!0,config:!0,map:!0};A(a,function(a,b){c[b]?(k[b]||(k[b]={}),U(k[b],a,!0,!0)):k[b]=a});a.bundles&&A(a.bundles,function(a,b){v(a, +function(a){a!==b&&(aa[a]=b)})});a.shim&&(A(a.shim,function(a,c){H(a)&&(a={deps:a});if((a.exports||a.init)&&!a.exportsFn)a.exportsFn=h.makeShimExports(a);b[c]=a}),k.shim=b);a.packages&&v(a.packages,function(a){var b,a="string"===typeof a?{name:a}:a;b=a.name;a.location&&(k.paths[b]=a.location);k.pkgs[b]=a.name+"/"+(a.main||"main").replace(ha,"").replace(Q,"")});A(m,function(a,b){!a.inited&&!a.map.unnormalized&&(a.map=i(b,null,!0))});if(a.deps||a.callback)h.require(a.deps||[],a.callback)},makeShimExports:function(a){return function(){var b; +a.init&&(b=a.init.apply(ba,arguments));return b||a.exports&&da(a.exports)}},makeRequire:function(a,j){function g(c,d,p){var k,n;j.enableBuildCallback&&(d&&G(d))&&(d.__requireJsBuild=!0);if("string"===typeof c){if(G(d))return w(B("requireargs","Invalid require call"),p);if(a&&t(L,c))return L[c](m[a.id]);if(e.get)return e.get(h,c,a,g);k=i(c,a,!1,!0);k=k.id;return!t(q,k)?w(B("notloaded",'Module name "'+k+'" has not been loaded yet for context: '+b+(a?"":". Use require([])"))):q[k]}J();h.nextTick(function(){J(); +n=r(i(null,a));n.skipMap=j.skipMap;n.init(c,d,p,{enabled:!0});D()});return g}j=j||{};U(g,{isBrowser:z,toUrl:function(b){var d,e=b.lastIndexOf("."),j=b.split("/")[0];if(-1!==e&&(!("."===j||".."===j)||1g.attachEvent.toString().indexOf("[native code"))&&!Y?(M=!0,g.attachEvent("onreadystatechange",b.onScriptLoad)):(g.addEventListener("load",b.onScriptLoad,!1),g.addEventListener("error",b.onScriptError,!1));g.src=d;J=g;D?y.insertBefore(g,D):y.appendChild(g);J=null;return g}if(ea)try{importScripts(d),b.completeLoad(c)}catch(i){b.onError(B("importscripts", +"importScripts failed for "+c+" at "+d,i,[c]))}};z&&!s.skipDataMain&&T(document.getElementsByTagName("script"),function(b){y||(y=b.parentNode);if(I=b.getAttribute("data-main"))return r=I,s.baseUrl||(E=r.split("/"),r=E.pop(),O=E.length?E.join("/")+"/":"./",s.baseUrl=O),r=r.replace(Q,""),e.jsExtRegExp.test(r)&&(r=I),s.deps=s.deps?s.deps.concat(r):[r],!0});define=function(b,c,d){var e,g;"string"!==typeof b&&(d=c,c=b,b=null);H(c)||(d=c,c=null);!c&&G(d)&&(c=[],d.length&&(d.toString().replace(ja,"").replace(ka, +function(b,d){c.push(d)}),c=(1===d.length?["require"]:["require","exports","module"]).concat(c)));if(M){if(!(e=J))N&&"interactive"===N.readyState||T(document.getElementsByTagName("script"),function(b){if("interactive"===b.readyState)return N=b}),e=N;e&&(b||(b=e.getAttribute("data-requiremodule")),g=F[e.getAttribute("data-requirecontext")])}g?(g.defQueue.push([b,c,d]),g.defQueueMap[b]=!0):R.push([b,c,d])};define.amd={jQuery:!0};e.exec=function(b){return eval(b)};e(s)}})(this); diff --git a/test/libs/should.min.js b/test/libs/should.min.js new file mode 100644 index 0000000..4c34de9 --- /dev/null +++ b/test/libs/should.min.js @@ -0,0 +1,9 @@ +/*! + * should - test framework agnostic BDD-style assertions + * @version v7.1.0 + * @author TJ Holowaychuk and contributors + * @link https://github.com/shouldjs/should.js + * @license MIT + */ +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Should=t()}}(function(){return function t(e,r,a){function n(s,i){if(!r[s]){if(!e[s]){var u="function"==typeof require&&require;if(!i&&u)return u(s,!0);if(o)return o(s,!0);var c=new Error("Cannot find module '"+s+"'");throw c.code="MODULE_NOT_FOUND",c}var h=r[s]={exports:{}};e[s][0].call(h.exports,function(t){var r=e[s][1][t];return n(r?r:t)},h,h.exports,t,e,r,a)}return r[s].exports}for(var o="function"==typeof require&&require,s=0;s=0){var s=r.indexOf("\n",n+1);r=r.substring(s+1)}}this.stack=r}}},i=" ";s.prototype=Object.create(Error.prototype,{name:{value:"AssertionError"},generateMessage:{value:function(){if(!this.operator&&this.previous)return this.previous.message;var t=o.format(this.actual),e="expected"in this?" "+o.format(this.expected):"",r="details"in this&&this.details?" ("+this.details+")":"",a=this.previous?"\n"+n(this.previous.message):"";return"expected "+t+(this.negate?" not ":" ")+this.operator+e+r+a}}}),e.exports=s},{"./util":18}],3:[function(t,e,r){function a(t){this.obj=t,this.anyOne=!1,this.negate=!1,this.params={actual:t}}var n=t("./assertion-error");t("./util");a.add=function(t,e){var r={enumerable:!0,configurable:!0};r.value=function(){var r=new a(this.obj,this,t);r.anyOne=this.anyOne;try{e.apply(r,arguments)}catch(o){if(o instanceof n){if(this.negate)return this.obj=r.obj,this.negate=!1,this;r!==o.assertion&&(r.params.previous=o),r.negate=!1,r.fail()}throw o}return this.negate&&(r.negate=!0,r.params.details="false negative fail",r.fail()),this.params.operator||(this.params=r.params),this.obj=r.obj,this.negate=!1,this},Object.defineProperty(a.prototype,t,r)},a.addChain=function(t,e){e=e||function(){},Object.defineProperty(a.prototype,t,{get:function(){return e(),this},enumerable:!0})},a.alias=function(t,e){var r=Object.getOwnPropertyDescriptor(a.prototype,t);if(!r)throw new Error("Alias "+t+" -> "+e+" could not be created as "+t+" not defined");Object.defineProperty(a.prototype,e,r)},a.prototype={constructor:a,assert:function(t){if(t)return this;var e=this.params;throw"obj"in e&&!("actual"in e)?e.actual=e.obj:"obj"in e||"actual"in e||(e.actual=this.obj),e.stackStartFunction=e.stackStartFunction||this.assert,e.negate=this.negate,e.assertion=this,new n(e)},fail:function(){return this.assert(!1)},get not(){return this.negate=!this.negate,this},get any(){return this.anyOne=!0,this}},e.exports=a},{"./assertion-error":2,"./util":18}],4:[function(t,e,r){var a=t("should-format").Formatter,n={checkProtoEql:!1,getFormatter:function(t){return new a(t||n)}};e.exports=n},{"should-format":21}],5:[function(t,e,r){function a(t,e,r,n,o){var s=new i(t);s.params={operator:n,expected:e,message:r,stackStartFunction:o||a},s.fail()}function n(t,e){t||a(t,!0,e,"==",h.ok)}function o(t,e){return t&&e?"[object RegExp]"==Object.prototype.toString.call(e)?e.test(t):t instanceof e?!0:e.call({},t)===!0?!0:!1:!1}function s(t,e,r,n){var s;"string"==typeof r&&(n=r,r=null);try{e()}catch(i){s=i}if(n=(r&&r.name?" ("+r.name+")":".")+(n?" "+n:"."),t&&!s&&a(s,r,"Missing expected exception"+n),!t&&o(s,r)&&a(s,r,"Got unwanted exception"+n),t&&s&&r&&!o(s,r)||!t&&s)throw s}var i=t("./../assertion"),u=t("should-equal"),c=Array.prototype.slice,h=e.exports=n;h.fail=a,h.ok=n,h.equal=function(t,e,r){t!=e&&a(t,e,r,"==",h.equal)},h.notEqual=function(t,e,r){t==e&&a(t,e,r,"!=",h.notEqual)},h.deepEqual=function(t,e,r){u(t,e).result||a(t,e,r,"deepEqual",h.deepEqual)},h.notDeepEqual=function(t,e,r){u(t,e).result&&a(t,e,r,"notDeepEqual",h.notDeepEqual)},h.strictEqual=function(t,e,r){t!==e&&a(t,e,r,"===",h.strictEqual)},h.notStrictEqual=function(t,e,r){t===e&&a(t,e,r,"!==",h.notStrictEqual)},h["throws"]=function(t,e,r){s.apply(this,[!0].concat(c.call(arguments)))},h.doesNotThrow=function(t,e){s.apply(this,[!1].concat(c.call(arguments)))},h.ifError=function(t){if(t)throw t}},{"./../assertion":3,"should-equal":20}],6:[function(t,e,r){var a=t("../util"),n=t("./_assert"),o=t("../assertion-error");e.exports=function(t){var e=t.format;a.merge(t,n),t.exist=t.exists=function(r,a){if(null==r)throw new o({message:a||"expected "+e(r)+" to exist",stackStartFunction:t.exist})},t.not={},t.not.exist=t.not.exists=function(r,a){if(null!=r)throw new o({message:a||"expected "+e(r)+" to not exist",stackStartFunction:t.not.exist})}}},{"../assertion-error":2,"../util":18,"./_assert":5}],7:[function(t,e,r){e.exports=function(t,e){e.add("true",function(){this.is.exactly(!0)}),e.alias("true","True"),e.add("false",function(){this.is.exactly(!1)}),e.alias("false","False"),e.add("ok",function(){this.params={operator:"to be truthy"},this.assert(this.obj)})}},{}],8:[function(t,e,r){e.exports=function(t,e){["an","of","a","and","be","has","have","with","is","which","the","it"].forEach(function(t){e.addChain(t)})}},{}],9:[function(t,e,r){var a=t("../util"),n=t("should-equal");e.exports=function(t,e){var r=t.format;e.add("containEql",function(t){this.params={operator:"to contain "+r(t)},this.is.not["null"]().and.not.undefined();var e=this.obj;"string"==typeof e?this.assert(e.indexOf(String(t))>=0):a.isIndexable(e)?this.assert(a.some(e,function(e){return n(e,t).result})):this.have.properties(t)}),e.add("containDeepOrdered",function(e){this.params={operator:"to contain "+r(e)};var n=this.obj;if("string"==typeof n)this.is.equal(String(e));else if(a.isIndexable(n)&&a.isIndexable(e)){for(var o=0,s=0,i=a.length(n),u=a.length(e);i>o&&u>s;o++)try{t(n[o]).containDeepOrdered(e[s]),s++}catch(c){if(c instanceof t.AssertionError)continue;throw c}this.assert(s===u)}else null!=n&&null!=e&&"object"==typeof n&&"object"==typeof e?(a.forEach(e,function(e,r){t(n[r]).containDeepOrdered(e)}),a.isEmptyObject(e)&&this.eql(e)):this.eql(e)}),e.add("containDeep",function(e){this.params={operator:"to contain "+r(e)};var n=this.obj;if("string"==typeof n)this.is.equal(String(e));else if(a.isIndexable(n)&&a.isIndexable(e)){var o={};a.forEach(e,function(e){this.assert(a.some(n,function(r,a){if(a in o)return!1;try{return t(r).containDeep(e),o[a]=!0,!0}catch(n){if(n instanceof t.AssertionError)return!1;throw n}}))},this)}else null!=n&&null!=e&&"object"==typeof n&&"object"==typeof e?(a.forEach(e,function(e,r){t(n[r]).containDeep(e)}),a.isEmptyObject(e)&&this.eql(e)):this.eql(e)})}},{"../util":18,"should-equal":20}],10:[function(t,e,r){function a(t,e,r){return((t.path.length>0?"at "+t.path.map(s.formatProp).join(" -> "):"")+(t.a===e?"":", A has "+s.format(t.a))+(t.b===r?"":" and B has "+s.format(t.b))+(t.showReason?" because "+t.reason:"")).trim()}var n=t("should-equal"),o=t("should-type"),s=t("../util");e.exports=function(t,e){function r(r,a,n){e.add(r,function(e){1!==arguments.length?e=Array.prototype.slice.call(arguments):t(e).be.Array(),this.params={operator:a,expected:e};var r=this.obj,o=!1;s.forEach(e,function(e){try{return t(e)[n](r),o=!0,!1}catch(a){if(a instanceof t.AssertionError)return;throw a}}),this.assert(o)})}e.add("eql",function(e,r){this.params={operator:"to equal",expected:e,message:r};var s=n(this.obj,e,t.config);this.params.details=s.result?"":a(s,this.obj,e),this.params.showDiff=n(o(this.obj),o(e)).result,this.assert(s.result)}),e.add("equal",function(t,e){this.params={operator:"to be",expected:t,message:e},this.params.showDiff=n(o(this.obj),o(t)).result,this.assert(t===this.obj)}),e.alias("equal","exactly"),e.alias("eql","deepEqual"),r("equalOneOf","to be equals one of","equal"),r("oneOf","to be one of","eql")}},{"../util":18,"should-equal":20,"should-type":23}],11:[function(t,e,r){var a=t("../util");e.exports=function(t,e){var r=t.format;e.add("throw",function(e,n){var o=this.obj,s={},i="",u=!1;if(a.isGeneratorFunction(o))return t(o())["throw"](e,n);if(a.isGeneratorObject(o))return t(o.next.bind(o))["throw"](e,n);this.is.a.Function();var c=!0;try{o()}catch(h){u=!0,s=h}if(u)if(e){if("string"==typeof e)c=e==s.message;else if(e instanceof RegExp)c=e.test(s.message);else if("function"==typeof e)c=s instanceof e;else if(null!=e)try{t(s).match(e)}catch(h){if(!(h instanceof t.AssertionError))throw h;i=": "+h.message,c=!1}if(c){if("function"==typeof e&&n)try{t(s).match(n)}catch(h){if(!(h instanceof t.AssertionError))throw h;i=": "+h.message,c=!1}}else"string"==typeof e||e instanceof RegExp?i=" with a message matching "+r(e)+", but got '"+s.message+"'":"function"==typeof e&&(i=" of type "+a.functionName(e)+", but got "+a.functionName(s.constructor))}else i=" (got "+r(s)+")";this.params={operator:"to throw exception"+i},this.assert(u),this.assert(c)}),e.alias("throw","throwError")}},{"../util":18}],12:[function(t,e,r){var a=t("../util"),n=t("should-equal");e.exports=function(t,e){var r=t.format;e.add("match",function(e,o){if(this.params={operator:"to match "+r(e),message:o},!n(this.obj,e).result)if(e instanceof RegExp){if("string"==typeof this.obj)this.assert(e.exec(this.obj));else if(a.isIndexable(this.obj))a.forEach(this.obj,function(t){this.assert(e.exec(t))},this);else if(null!=this.obj&&"object"==typeof this.obj){var s=[],i=[];a.forEach(this.obj,function(t,n){e.exec(t)?i.push(a.formatProp(n)):s.push(a.formatProp(n)+" ("+r(t)+")")},this),s.length&&(this.params.operator+="\n not matched properties: "+s.join(", ")),i.length&&(this.params.operator+="\n matched properties: "+i.join(", ")),this.assert(0===s.length)}}else if("function"==typeof e){var u;u=e(this.obj),"boolean"==typeof u&&this.assert(u)}else null!=e&&"object"==typeof e?(s=[],i=[],a.forEach(e,function(e,n){try{t(this.obj).have.property(n).which.match(e),i.push(a.formatProp(n))}catch(o){if(!(o instanceof t.AssertionError))throw o;s.push(a.formatProp(n)+" ("+r(this.obj[n])+")")}},this),s.length&&(this.params.operator+="\n not matched properties: "+s.join(", ")),i.length&&(this.params.operator+="\n matched properties: "+i.join(", ")),this.assert(0===s.length)):this.assert(!1)}),e.add("matchEach",function(e,n){this.params={operator:"to match each "+r(e),message:n},a.forEach(this.obj,function(r){t(r).match(e)},this)}),e.add("matchAny",function(e,n){this.params={operator:"to match any "+r(e),message:n},this.assert(a.some(this.obj,function(r){try{return t(r).match(e),!0}catch(a){if(a instanceof t.AssertionError)return!1;throw a}}))}),e.alias("matchAny","matchSome"),e.alias("matchEach","matchEvery")}},{"../util":18,"should-equal":20}],13:[function(t,e,r){e.exports=function(t,e){e.add("NaN",function(){this.params={operator:"to be NaN"},this.assert(this.obj!==this.obj)}),e.add("Infinity",function(){this.params={operator:"to be Infinity"},this.is.a.Number().and.not.a.NaN().and.assert(!isFinite(this.obj))}),e.add("within",function(t,e,r){this.params={operator:"to be within "+t+".."+e,message:r},this.assert(this.obj>=t&&this.obj<=e)}),e.add("approximately",function(t,e,r){this.params={operator:"to be approximately "+t+" ±"+e,message:r},this.assert(Math.abs(this.obj-t)<=e)}),e.add("above",function(t,e){this.params={operator:"to be above "+t,message:e},this.assert(this.obj>t)}),e.add("below",function(t,e){this.params={operator:"to be below "+t,message:e},this.assert(this.obj=t)}),e.add("belowOrEqual",function(t,e){this.params={operator:"to be below or equal"+t,message:e},this.assert(this.obj<=t)}),e.alias("aboveOrEqual","greaterThanOrEqual"),e.alias("belowOrEqual","lessThanOrEqual")}},{}],14:[function(t,e,r){var a=t("../util"),n=t("should-equal"),o=Array.prototype.slice;e.exports=function(t,e){function r(){var t={};if(arguments.length>1)t.names=o.call(arguments);else{var e=arguments[0];"string"==typeof e?t.names=[e]:a.isIndexable(e)?t.names=e:(t.names=Object.keys(e),t.values=e)}return t}var s=t.format;e.add("propertyWithDescriptor",function(e,r){this.params={actual:this.obj,operator:"to have own property with descriptor "+s(r)};var a=this.obj;this.have.ownProperty(e),t(Object.getOwnPropertyDescriptor(Object(a),e)).have.properties(r)}),e.add("enumerable",function(t,e){t=a.convertPropertyName(t),this.params={operator:"to have enumerable property "+a.formatProp(t)+(arguments.length>1?" equal to "+s(e):"")};var r={enumerable:!0};arguments.length>1&&(r.value=e),this.have.propertyWithDescriptor(t,r)}),e.add("enumerables",function(e){var n=r.apply(null,arguments);this.params={operator:"to have enumerables "+n.names.map(a.formatProp)};var o=this.obj;n.names.forEach(function(e){t(o).have.enumerable(e)})}),e.add("property",function(t,e){if(t=a.convertPropertyName(t),arguments.length>1){var r={};r[t]=e,this.have.properties(r)}else this.have.properties(t);this.obj=this.obj[t]}),e.add("properties",function(t){var e={};arguments.length>1?t=o.call(arguments):Array.isArray(t)||("string"==typeof t||"symbol"==typeof t?t=[t]:(e=t,t=Object.keys(t)));var r=Object(this.obj),i=[];t.forEach(function(t){t in r||i.push(a.formatProp(t))});var u=i;0===u.length?u=t.map(a.formatProp):this.anyOne&&(u=t.filter(function(t){return i.indexOf(a.formatProp(t))<0}).map(a.formatProp));var c=(1===u.length?"to have property ":"to have "+(this.anyOne?"any of ":"")+"properties ")+u.join(", ");this.params={obj:this.obj,operator:c},this.assert(0===i.length||this.anyOne&&i.length!=t.length);var h=Object.keys(e);if(h.length){var p=[];u=[],h.forEach(function(t){var o=e[t];n(r[t],o).result?u.push(a.formatProp(t)+" of "+s(o)):p.push(a.formatProp(t)+" of "+s(o)+" (got "+s(r[t])+")")}),(0!==p.length&&!this.anyOne||this.anyOne&&0===u.length)&&(u=p),c=(1===u.length?"to have property ":"to have "+(this.anyOne?"any of ":"")+"properties ")+u.join(", "),this.params={obj:this.obj,operator:c},this.assert(0===p.length||this.anyOne&&p.length!=h.length)}}),e.add("length",function(t,e){this.have.property("length",t,e)}),e.alias("length","lengthOf");var i=Object.prototype.hasOwnProperty;e.add("ownProperty",function(t,e){t=a.convertPropertyName(t),this.params={actual:this.obj,operator:"to have own property "+a.formatProp(t),message:e},this.assert(i.call(this.obj,t)),this.obj=this.obj[t]}),e.alias("ownProperty","hasOwnProperty"),e.add("empty",function(){if(this.params={operator:"to be empty"},void 0!==a.length(this.obj))t(this.obj).have.property("length",0);else{var e=Object(this.obj);for(var r in e)t(this.obj).not.have.ownProperty(r)}},!0),e.add("keys",function(t){arguments.length>1?t=o.call(arguments):1===arguments.length&&"string"==typeof t?t=[t]:0===arguments.length&&(t=[]),t=t.map(String);var e=Object(this.obj),r=[];t.forEach(function(t){i.call(this.obj,t)||r.push(a.formatProp(t))},this);var n=[];Object.keys(e).forEach(function(e){t.indexOf(e)<0&&n.push(a.formatProp(e))});var s=0===t.length?"to be empty":"to have "+(1===t.length?"key ":"keys ");this.params={operator:s+t.map(a.formatProp).join(", ")},r.length>0&&(this.params.operator+="\n missing keys: "+r.join(", ")),n.length>0&&(this.params.operator+="\n extra keys: "+n.join(", ")),this.assert(0===r.length&&0===n.length)}),e.alias("keys","key"),e.add("propertyByPath",function(e){arguments.length>1?e=o.call(arguments):1===arguments.length&&"string"==typeof e?e=[e]:0===arguments.length&&(e=[]);var r=e.map(a.formatProp);e=e.map(String);for(var n,s=t(Object(this.obj)),i=[];n=e.shift();)this.params={operator:"to have property by path "+r.join(", ")+" - failed on "+a.formatProp(n)},s=s.have.property(n),i.push(n);this.params={obj:this.obj,operator:"to have property by path "+r.join(", ")},this.obj=s.obj})}},{"../util":18,"should-equal":20}],15:[function(t,e,r){e.exports=function(t,e){e.add("startWith",function(e,r){this.params={operator:"to start with "+t.format(e),message:r},this.assert(0===this.obj.indexOf(e))}),e.add("endWith",function(e,r){this.params={operator:"to end with "+t.format(e),message:r},this.assert(this.obj.indexOf(e,this.obj.length-e.length)>=0)})}},{}],16:[function(t,e,r){var a=t("../util");e.exports=function(t,e){e.add("Number",function(){this.params={operator:"to be a number"},this.have.type("number")}),e.add("arguments",function(){this.params={operator:"to be arguments"},this.have["class"]("Arguments")}),e.alias("arguments","Arguments"),e.add("type",function(e,r){this.params={operator:"to have type "+e,message:r},t(typeof this.obj).be.exactly(e)}),e.add("instanceof",function(t,e){this.params={operator:"to be an instance of "+a.functionName(t),message:e},this.assert(Object(this.obj)instanceof t)}),e.alias("instanceof","instanceOf"),e.add("Function",function(){this.params={operator:"to be a function"},this.have.type("function")}),e.add("Object",function(){this.params={operator:"to be an object"},this.is.not["null"]().and.have.type("object")}),e.add("String",function(){this.params={operator:"to be a string"},this.have.type("string")}),e.add("Array",function(){this.params={operator:"to be an array"},this.have["class"]("Array")}),e.add("Boolean",function(){this.params={operator:"to be a boolean"},this.have.type("boolean")}),e.add("Error",function(){this.params={operator:"to be an error"},this.have.instanceOf(Error)}),e.add("null",function(){this.params={operator:"to be null"},this.assert(null===this.obj)}),e.alias("null","Null"),e.add("class",function(t){this.params={operator:"to have [[Class]] "+t},this.assert(Object.prototype.toString.call(this.obj)==="[object "+t+"]")}),e.alias("class","Class"),e.add("undefined",function(){this.params={operator:"to be undefined"},this.assert(void 0===this.obj)}),e.alias("undefined","Undefined"),e.add("iterable",function(){this.params={operator:"to be iterable"},t(this.obj).have.property(Symbol.iterator).which.is.a.Function()}),e.add("iterator",function(){this.params={operator:"to be iterator"},t(this.obj).have.property("next").which.is.a.Function()}),e.add("generator",function(){this.params={operator:"to be generator"},t(this.obj).be.iterable.and.iterator.and.it.is.equal(this.obj[Symbol.iterator]())})}},{"../util":18}],17:[function(t,e,r){var a=t("./util"),n=function o(t){return new o.Assertion(t)};n.AssertionError=t("./assertion-error"),n.Assertion=t("./assertion"),n.format=a.format,n.type=t("should-type"),n.util=a,n.config=t("./config"),r=e.exports=n,n.extend=function(t,e){t=t||"should",e=e||Object.prototype;var r=Object.getOwnPropertyDescriptor(e,t);return Object.defineProperty(e,t,{set:function(){},get:function(){return n(a.isWrapperType(this)?this.valueOf():this)},configurable:!0}),{name:t,descriptor:r,proto:e}},n.noConflict=function(t){return t=t||n._prevShould,t&&(delete t.proto[t.name],t.descriptor&&Object.defineProperty(t.proto,t.name,t.descriptor)),n},n.use=function(t){return t(n,n.Assertion),this},n.use(t("./ext/assert")).use(t("./ext/chain")).use(t("./ext/bool")).use(t("./ext/number")).use(t("./ext/eql")).use(t("./ext/type")).use(t("./ext/string")).use(t("./ext/property")).use(t("./ext/error")).use(t("./ext/match")).use(t("./ext/contain"))},{"./assertion":3,"./assertion-error":2,"./config":4,"./ext/assert":6,"./ext/bool":7,"./ext/chain":8,"./ext/contain":9,"./ext/eql":10,"./ext/error":11,"./ext/match":12,"./ext/number":13,"./ext/property":14,"./ext/string":15,"./ext/type":16,"./util":18,"should-type":23}],18:[function(t,e,r){var a=t("should-type"),n=t("./config");r.isWrapperType=function(t){return t instanceof Number||t instanceof String||t instanceof Boolean},r.merge=function(t,e){if(t&&e)for(var r in e)t[r]=e[r];return t};var o=Object.prototype.hasOwnProperty;r.forEach=function s(t,e,a){if(r.isGeneratorFunction(t))return s(t(),e,a);if(r.isGeneratorObject(t))for(var n=t.next();!n.done;){if(e.call(a,n.value,"value",t)===!1)return;n=t.next()}else for(var i in t)if(o.call(t,i)&&e.call(a,t[i],i,t)===!1)return},r.some=function(t,e,a){var n=!1;return r.forEach(t,function(r,o){return e.call(a,r,o,t)?(n=!0,!1):void 0},a),n},r.isEmptyObject=function(t){for(var e in t)if(o.call(t,e))return!1;return!0},r.isIndexable=function(t){var e=a(t);return e.type===a.OBJECT&&e.cls===a.ARRAY||e.type===a.OBJECT&&e.cls===a.BUFFER||e.type===a.OBJECT&&e.cls===a.ARGUMENTS||e.type===a.OBJECT&&e.cls===a.ARRAY_BUFFER||e.type===a.OBJECT&&e.cls===a.TYPED_ARRAY||e.type===a.OBJECT&&e.cls===a.DATA_VIEW||e.type===a.OBJECT&&e.cls===a.STRING||e.type===a.STRING},r.length=function(t){var e=a(t);switch(e.type){case a.STRING:return t.length;case a.OBJECT:switch(e.cls){case a.ARRAY_BUFFER:case a.TYPED_ARRAY:case a.DATA_VIEW:return t.byteLength;case a.ARRAY:case a.BUFFER:case a.ARGUMENTS:case a.FUNCTION:return t.length}}},r.convertPropertyName=function(t){return"symbol"==typeof t?t:String(t)},r.isGeneratorObject=function(t){return t?"function"==typeof t.next&&"function"==typeof t[Symbol.iterator]&&t[Symbol.iterator]()===t:!1},r.isGeneratorFunction=function(t){return"function"!=typeof t?!1:/^function\s*\*\s*/.test(t.toString())},r.format=function(t,e){return n.getFormatter(e).format(t)},r.functionName=t("should-format").Formatter.functionName,r.formatProp=function(t){return n.getFormatter().formatPropertyName(String(t))}},{"./config":4,"should-format":21,"should-type":23}],19:[function(t,e,r){e.exports=function(t){for(var e=arguments,r=1,a=e.length;a>r;r++)t=t.replace(/%s/,e[r]);return t}},{}],20:[function(t,e,r){function a(t,e,r,a,n){var o={result:t};return t||(o.path=e,o.reason=r,o.a=a,o.b=n),o}function n(t){return t.type+(t.cls?"("+t.cls+(t.sub?" "+t.sub:"")+")":"")}function o(t,e,r,s,f,l){function d(r,n){return a(r,l,n,t,e)}function m(a){return o(t[a],e[a],r,s,f,l.concat([a]))}var b=h;if(t===e)return d(0!==t||1/t==1/e,p.PLUS_0_AND_MINUS_0);var y,g,v=i(t),j=i(e),E=v.type!==j.type||v.cls!==j.cls;if(E||r.checkSubType&&v.sub!==j.sub||!r.checkSubType)return d(!1,u(p.DIFFERENT_TYPES,n(v),n(j)));switch(v.type){case"number":return t!==t?d(e!==e,p.NAN_NUMBER):0===t?d(1/t===1/e,p.PLUS_0_AND_MINUS_0):d(t===e,p.EQUALITY);case"boolean":case"string":return d(t===e,p.EQUALITY);case"function":var O=t.toString(),A=e.toString();if(b=o(O,A,r,s,f,l),!b.result)return b.reason=p.FUNCTION_SOURCES,b;break;case"object":switch(v.cls){case"regexp":for(g=["source","global","multiline","lastIndex","ignoreCase"];g.length;)if(b=m(g.shift()),!b.result)return b;break;case"date":if(+t!==+e)return d(!1,p.EQUALITY);break;case"number":case"boolean":case"string":if(b=o(t.valueOf(),e.valueOf(),r,s,f,l),!b.result)return b.reason=p.WRAPPED_VALUE,b;break;case"buffer":if(b=m("length"),!b.result)return b;for(y=t.length;y--;)if(b=m(y),!b.result)return b;return h;case"error":for(g=["name","message"];g.length;)if(b=m(g.shift()),!b.result)return b;break;case"array":case"arguments":case"typed-array":if(b=m("length"),!b.result)return b;break;case"array-buffer":if(b=m("byteLength"),!b.result)return b;break;case"map":case"set":if(b=m("size"),!b.result)return b;s.push(t),f.push(e);for(var x=t.entries(),S=x.next();!S.done;){var T=S.value[0];if("object"!=i(T).type){if(!e.has(T)){b=d(!1,p.SET_MAP_MISSING_KEY),b.a=T,b.b=T;break}if("map"==v.cls){var _=e.get(T);if(b=o(S.value[1],_,r,s,f,l),!b.result){b.a=S.value,b.b=_,b.reason=p.MAP_VALUE_EQUALITY;break}}}else for(var P=e.entries(),N=P.next();!N.done;){if(b=o(S.value[0],N.value[0],r,s,f,l),b.result){"map"==v.cls&&(b=o(S.value[1],N.value[1],r,s,f,l),b.result||(b.a=S.value,b.b=N.value,b.reason=p.MAP_VALUE_EQUALITY));break}b.reason=p.SET_MAP_MISSING_KEY,b.a=T,b.b=T,N=P.next()}if(!b.result)break;S=x.next()}if(s.pop(),f.pop(),!b.result)return b.reason=p.SET_MAP_MISSING_ENTRY,b}}for(y=s.length;y--;)if(s[y]==t)return d(f[y]==e,p.CIRCULAR_VALUES);s.push(t),f.push(e);var T;for(T in e)if(c.call(e,T)){if(b=d(c.call(t,T),u(p.MISSING_KEY,"A",T)),!b.result)break;if(b.result&&(b=m(T),!b.result))break}if(b.result)for(T in t)if(c.call(t,T)&&(b=d(c.call(e,T),u(p.MISSING_KEY,"B",T)),!b.result))return b;if(s.pop(),f.pop(),!b.result)return b;var R=!1,w=!1;return r.checkProtoEql&&(Object.getPrototypeOf?(R=Object.getPrototypeOf(t)===Object.getPrototypeOf(e),w=!0):t.__proto__&&e.__proto__&&(R=t.__proto__===e.__proto__,w=!0),w&&!R&&(b=d(R,p.EQUALITY_PROTOTYPE),b.showReason=!0,!b.result))?b:h}function s(t,e,r){r=r||{},"boolean"!=typeof r.checkProtoEql&&(r.checkProtoEql=f.checkProtoEql),"boolean"!=typeof r.checkSubType&&(r.checkSubType=f.checkSubType);var a=o(t,e,r,[],[],[]);return a}var i=t("should-type"),u=t("./format"),c=Object.prototype.hasOwnProperty,h=a(!0),p={PLUS_0_AND_MINUS_0:"+0 is not equal to -0",DIFFERENT_TYPES:"A has type %s and B has type %s",NAN_NUMBER:"NaN is not equal to any number",EQUALITY:"A is not equal to B",EQUALITY_PROTOTYPE:"A and B have different prototypes",WRAPPED_VALUE:"A wrapped value is not equal to B wrapped value",FUNCTION_SOURCES:"function A is not equal to B by source code value (via .toString call)",MISSING_KEY:"%s has no key %s",CIRCULAR_VALUES:"A has circular reference that was visited not in the same time as B",SET_MAP_MISSING_KEY:"Set/Map missing key",MAP_VALUE_EQUALITY:"Values of the same key in A and B is not equal"},f={checkProtoEql:!0,checkSubType:!0};e.exports=s,s.r=p},{"./format":19,"should-type":23}],21:[function(t,e,r){function a(t){return function(e){var r=t(e);return r.sort(),r}}function n(t){t=t||{},this.seen=[],this.keys=a(t.keys===!1?Object.getOwnPropertyNames:Object.keys),this.maxLineLength="number"==typeof t.maxLineLength?t.maxLineLength:60,this.propSep=t.propSep||",",this.isUTCdate=!!t.isUTCdate}function o(t,e){var r=e?"UTC":"",a=t["get"+r+"FullYear"]()+"-"+u.pad0(t["get"+r+"Month"]()+1,2)+"-"+u.pad0(t["get"+r+"Date"](),2),n=u.pad0(t["get"+r+"Hours"](),2)+":"+u.pad0(t["get"+r+"Minutes"](),2)+":"+u.pad0(t["get"+r+"Seconds"](),2)+"."+u.pad0(t["get"+r+"Milliseconds"](),3),o=t.getTimezoneOffset(),s=Math.abs(o),i=Math.floor(s/60),c=s-60*i,h=(0>o?"+":"-")+u.pad0(i,2)+u.pad0(c,2);return a+" "+n+(e?"":" "+h)}function s(t,e){return new n(e).format(t)}var i=t("should-type"),u=t("./util");n.prototype={constructor:n,format:function(t){var e=i(t),r=e.type,a=e.type;e.cls&&(r+="_"+e.cls,a+="_"+e.cls),e.sub&&(a+="_"+e.sub);var n=this["_format_"+a]||this["_format_"+r]||this["_format_"+e.type]||this.defaultFormat;return n.call(this,t).trim()},_formatObject:function(t,e){e=e||{};var r=e.keys||this.keys(t),a=0,o=e.formatPropertyValue||this.formatPropertyValue,s=e.formatPropertyName||this.formatPropertyName,i=e.keyValueSep||": ",c=e.keyFilter||function(){return!0};this.seen.push(t);var h=[];r.forEach(function(e){if(c(e)){var r=s.call(this,e),n=(r?r+i:"")+o.call(this,t,e);a+=n.length,h.push(n)}},this),this.seen.pop(),(e.additionalProperties||[]).forEach(function(t){var e=t[0]+i+this.format(t[1]);a+=e.length,h.push(e)},this);var p=e.prefix||n.constructorName(t)||"";p.length>0&&(p+=" ");var f,l;Array.isArray(e.brackets)?(f=e.brackets&&e.brackets[0],l=e.brackets&&e.brackets[1]):(f="{",l="}");var d=e.value||"";return 0===h.length?d||p+f+l:a<=this.maxLineLength?p+f+" "+(d?d+" ":"")+h.join(this.propSep+" ")+" "+l:p+f+"\n"+(d?" "+d+"\n":"")+h.map(u.addSpaces).join(this.propSep+"\n")+"\n"+l},formatObject:function(t,e,r){r=r||this.keys(t);var a=0;return this.seen.push(t),r=r.map(function(e){var r=this.formatProperty(t,e);return a+=r.length,r},this),this.seen.pop(),0===r.length?"{}":a<=this.maxLineLength?"{ "+(e?e+" ":"")+r.join(this.propSep+" ")+" }":"{\n"+(e?" "+e+"\n":"")+r.map(u.addSpaces).join(this.propSep+"\n")+"\n}"},formatPropertyName:function(t){return t.match(/^[a-zA-Z_$][a-zA-Z_$0-9]*$/)?t:this.format(t)},formatProperty:function(t,e){var r=n.getPropertyDescriptor(t,e),a=this.formatPropertyName(e),o=r.get&&r.set?"[Getter/Setter]":r.get?"[Getter]":r.set?"[Setter]":this.seen.indexOf(r.value)>=0?"[Circular]":this.format(r.value);return a+": "+o},formatPropertyValue:function(t,e){var r=n.getPropertyDescriptor(t,e),a=r.get&&r.set?"[Getter/Setter]":r.get?"[Getter]":r.set?"[Setter]":this.seen.indexOf(r.value)>=0?"[Circular]":this.format(r.value);return a}},n.add=function(t,e,r,a){var o=Array.prototype.slice.call(arguments);a=o.pop(),n.prototype["_format_"+o.join("_")]=a},n.formatObjectWithPrefix=function(t){return function(e){var r=t.call(this,e),a=this.keys(e);return 0==a.length?r:this.formatObject(e,r,a)}};var c=/^\s*function\s*(\S*)\s*\(/;n.functionName=function(t){if(t.name)return t.name;var e=t.toString().match(c)[1];return e},n.constructorName=function(t){for(;t;){var e=Object.getOwnPropertyDescriptor(t,"constructor");if(void 0!==e&&"function"==typeof e.value){var r=n.functionName(e.value);if(""!==r)return r}t=Object.getPrototypeOf(t)}},n.getPropertyDescriptor=function(t,e){var r;try{r=Object.getOwnPropertyDescriptor(t,e)||{value:t[e]}}catch(a){r={value:a}}return r},n.generateFunctionForIndexedArray=function(t,e,r){return function(a){for(var n=this.byteArrayMaxLength||50,o=a[t],s=[],i=0,c=0;n>c&&o>c;c++){var h=a[c]||0,p=u.pad0(h.toString(16),r);i+=p.length,s.push(p)}var f=a.constructor.name||e||"";return f&&(f+=" "),0===s.length?f+"[]":i<=this.maxLineLength?f+"[ "+s.join(this.propSep+" ")+" ]":f+"[\n"+s.map(u.addSpaces).join(this.propSep+"\n")+"\n]"}},["undefined","boolean","null","symbol"].forEach(function(t){n.add(t,String)}),["number","boolean"].forEach(function(t){n.add("object",t,function(t){return this._formatObject(t,{additionalProperties:[["[[PrimitiveValue]]",t.valueOf()]]})})}),n.add("object","string",function(t){var e=t.valueOf();return this._formatObject(t,{keyFilter:function(t){return!(t.match(/\d+/)&&parseInt(t,10)1/t?"-0":String(t)}),n.add("string",function(t){return"'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'"}),n.add("object",function(t){return this._formatObject(t)}),n.add("object","arguments",function(t){return this._formatObject(t,{prefix:"Arguments",formatPropertyName:function(t){return t.match(/\d+/)?void 0:this.formatPropertyName(t)},brackets:["[","]"]})}),n.add("object","array",function(t){return this._formatObject(t,{formatPropertyName:function(t){return t.match(/\d+/)?void 0:this.formatPropertyName(t)},brackets:["[","]"]})}),n.add("object","date",function(t){return this._formatObject(t,{value:o(t,this.isUTCdate)})}),n.add("function",function(t){return this._formatObject(t,{additionalProperties:[["name",n.functionName(t)]]})}),n.add("object","error",function(t){return this._formatObject(t,{prefix:t.name,additionalProperties:[["message",t.message]]})}),n.add("object","buffer",n.generateFunctionForIndexedArray("length","Buffer",2)),n.add("object","array-buffer",n.generateFunctionForIndexedArray("byteLength","ArrayBuffer",2)),n.add("object","typed-array","int8",n.generateFunctionForIndexedArray("length","Int8Array",2)),n.add("object","typed-array","uint8",n.generateFunctionForIndexedArray("length","Uint8Array",2)),n.add("object","typed-array","uint8clamped",n.generateFunctionForIndexedArray("length","Uint8ClampedArray",2)),n.add("object","typed-array","int16",n.generateFunctionForIndexedArray("length","Int16Array",4)),n.add("object","typed-array","uint16",n.generateFunctionForIndexedArray("length","Uint16Array",4)),n.add("object","typed-array","int32",n.generateFunctionForIndexedArray("length","Int32Array",8)),n.add("object","typed-array","uint32",n.generateFunctionForIndexedArray("length","Uint32Array",8)), +n.add("object","promise",function(){return"[Promise]"}),n.add("object","xhr",function(){return"[XMLHttpRequest]"}),n.add("object","html-element",function(t){return t.outerHTML}),n.add("object","html-element","#text",function(t){return t.nodeValue}),n.add("object","html-element","#document",function(t){return t.documentElement.outerHTML}),n.add("object","host",function(){return"[Host]"}),n.add("object","set",function(t){var e=t.values(),r=0;this.seen.push(t);for(var a=[],n=e.next();!n.done;){var o=n.value,s=this.format(o);r+=s.length,a.push(s),n=e.next()}return this.seen.pop(),0===a.length?"Set {}":r<=this.maxLineLength?"Set { "+a.join(this.propSep+" ")+" }":"Set {\n"+a.map(u.addSpaces).join(this.propSep+"\n")+"\n}"}),n.add("object","map",function(t){var e=t.entries(),r=0;this.seen.push(t);for(var a=[],n=e.next();!n.done;){var o,s=n.value,i=this.format(s[0]),c=this.format(s[1]);o=i.length+c.length+4<=this.maxLineLength?i+" => "+c:i+" =>\n"+c,r+=i.length+c.length+4,a.push(o),n=e.next()}return this.seen.pop(),0===a.length?"Map {}":r<=this.maxLineLength?"Map { "+a.join(this.propSep+" ")+" }":"Map {\n"+a.map(u.addSpaces).join(this.propSep+"\n")+"\n}"}),n.prototype.defaultFormat=n.prototype._format_object,s.Formatter=n,e.exports=s},{"./util":22,"should-type":23}],22:[function(t,e,r){function a(t){return t.split("\n").map(function(t){return" "+t}).join("\n")}function n(t,e,r){t=String(t);var a=!1;if(0>e&&(a=!0,e=-e),t.lengtha;a++){var o=this.checks[a].call(this,t,e,r);if("undefined"!=typeof o)return o}}};var u=new n;u.addTypeOf(i.NUMBER,i.NUMBER).addTypeOf(i.UNDEFINED,i.UNDEFINED).addTypeOf(i.STRING,i.STRING).addTypeOf(i.BOOLEAN,i.BOOLEAN).addTypeOf(i.FUNCTION,i.FUNCTION).addTypeOf(i.SYMBOL,i.SYMBOL).add(function(t,e){return null===t?new a(i.NULL):void 0}).addClass("[object String]",i.STRING).addClass("[object Boolean]",i.BOOLEAN).addClass("[object Number]",i.NUMBER).addClass("[object Array]",i.ARRAY).addClass("[object RegExp]",i.REGEXP).addClass("[object Error]",i.ERROR).addClass("[object Date]",i.DATE).addClass("[object Arguments]",i.ARGUMENTS).addClass("[object Math]").addClass("[object JSON]").addClass("[object ArrayBuffer]",i.ARRAY_BUFFER).addClass("[object Int8Array]",i.TYPED_ARRAY,"int8").addClass("[object Uint8Array]",i.TYPED_ARRAY,"uint8").addClass("[object Uint8ClampedArray]",i.TYPED_ARRAY,"uint8clamped").addClass("[object Int16Array]",i.TYPED_ARRAY,"int16").addClass("[object Uint16Array]",i.TYPED_ARRAY,"uint16").addClass("[object Int32Array]",i.TYPED_ARRAY,"int32").addClass("[object Uint32Array]",i.TYPED_ARRAY,"uint32").addClass("[object Float32Array]",i.TYPED_ARRAY,"float32").addClass("[object Float64Array]",i.TYPED_ARRAY,"float64").addClass("[object DataView]",i.DATA_VIEW).addClass("[object Map]",i.MAP).addClass("[object WeakMap]",i.WEAK_MAP).addClass("[object Set]",i.SET).addClass("[object WeakSet]",i.WEAK_SET).addClass("[object Promise]",i.PROMISE).addClass("[object Blob]",i.BLOB).addClass("[object File]",i.FILE).addClass("[object FileList]",i.FILE_LIST).addClass("[object XMLHttpRequest]",i.XHR).add(function(t){return typeof Promise===i.FUNCTION&&t instanceof Promise||typeof t.then===i.FUNCTION?new a(i.OBJECT,i.PROMISE):void 0}).add(function(t){return"undefined"!=typeof Buffer&&t instanceof Buffer?new a(i.OBJECT,i.BUFFER):void 0}).add(function(t){return"undefined"!=typeof Node&&t instanceof Node?new a(i.OBJECT,i.HTML_ELEMENT,t.nodeName):void 0}).add(function(t){return t.Boolean===Boolean&&t.Number===Number&&t.String===String&&t.Date===Date?new a(i.OBJECT,i.HOST):void 0}).add(function(){return new a(i.OBJECT)}),o.checker=u,o.TypeChecker=n,o.Type=a,Object.keys(i).forEach(function(t){o[t]=i[t]}),e.exports=o},{"./types":24}],24:[function(t,e,r){var a={NUMBER:"number",UNDEFINED:"undefined",STRING:"string",BOOLEAN:"boolean",OBJECT:"object",FUNCTION:"function",NULL:"null",ARRAY:"array",REGEXP:"regexp",DATE:"date",ERROR:"error",ARGUMENTS:"arguments",SYMBOL:"symbol",ARRAY_BUFFER:"array-buffer",TYPED_ARRAY:"typed-array",DATA_VIEW:"data-view",MAP:"map",SET:"set",WEAK_SET:"weak-set",WEAK_MAP:"weak-map",PROMISE:"promise",BUFFER:"buffer",HTML_ELEMENT:"html-element",HTML_ELEMENT_TEXT:"html-element-text",DOCUMENT:"document",WINDOW:"window",FILE:"file",FILE_LIST:"file-list",BLOB:"blob",HOST:"host",XHR:"xhr"};e.exports=a},{}]},{},[1])(1)}); \ No newline at end of file diff --git a/test/my.mock.wrapper.js b/test/my.mock.wrapper.js new file mode 100644 index 0000000..0fad3f0 --- /dev/null +++ b/test/my.mock.wrapper.js @@ -0,0 +1,908 @@ +// adds toISOString to date objects if not there +// from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString +if ( !Date.prototype.toISOString ) { + ( function() { + + function pad(number) { + var r = String(number); + if ( r.length === 1 ) { + r = '0' + r; + } + return r; + } + + Date.prototype.toISOString = function() { + return this.getUTCFullYear() + + '-' + pad( this.getUTCMonth() + 1 ) + + '-' + pad( this.getUTCDate() ) + + 'T' + pad( this.getUTCHours() ) + + ':' + pad( this.getUTCMinutes() ) + + ':' + pad( this.getUTCSeconds() ) + + '.' + String( (this.getUTCMilliseconds()/1000).toFixed(3) ).slice( 2, 5 ) + + 'Z'; + }; + + }() ); +} + +// shim for old-style Base64 lib +function toBase64(text){ + if(CryptoJS && CryptoJS.enc.Base64) + return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Latin1.parse(text)); + else + return Base64.encode(text); +} + +// shim for old-style crypto lib +function toSHA1(text){ + if(CryptoJS && CryptoJS.SHA1) + return CryptoJS.SHA1(text).toString(); + else + return Crypto.util.bytesToHex( Crypto.SHA1(text,{asBytes:true}) ); +} + +// check if string or object is date, if it is, return date object +// feburary 31st == march 3rd in this solution +function isDate(date) { + // check if object is being passed + if ( Object.prototype.toString.call(date) === "[object Date]" ) + var d = date; + else + var d = new Date(date); + // deep check on date object + if ( Object.prototype.toString.call(d) === "[object Date]" ) + { + // it is a date + if ( isNaN( d.valueOf() ) ) + { + ADL.XAPIWrapper.log("Invalid date String passed"); + return null; + } else { + return d; + } + } else { + // not a date + ADL.XAPIWrapper.log("Invalid date object"); + return null; + } +} + +(function(ADL){ + log.debug = false; + /* + * Config object used w/ url params to configure the lrs object + * change these to match your lrs + * @return {object} config object + * @example + * var conf = { + * "endpoint" : "https://lrs.adlnet.gov/xapi/", + * "auth" : "Basic " + toBase64('tom:1234'), + * }; + * ADL.XAPIWrapper.changeConfig(conf); + */ + var Config = function() + { + var conf = {}; + conf['endpoint'] = "http://localhost:8000/xapi/"; + try + { + conf['auth'] = "Basic " + toBase64('tom:1234'); + } + catch (e) + { + log("Exception in Config trying to encode auth: " + e); + } + + // Statement defaults + // conf["actor"] = {"mbox":"default@example.com"}; + // conf["registration"] = ruuid(); + // conf["grouping"] = {"id":"ctxact:default/grouping"}; + // conf["activity_platform"] = "default platform"; + return conf + }(); + + /* + * XAPIWrapper Constructor + * @param {object} config with a minimum of an endoint property + * @param {boolean} verifyxapiversion indicating whether to verify the version of the LRS is compatible with this wrapper + */ + XAPIWrapper = function(config, verifyxapiversion) + { + this.lrs = getLRSObject(config || {}); + if (this.lrs.user && this.lrs.password) + updateAuth(this.lrs, this.lrs.user, this.lrs.password); + this.base = getbase(this.lrs.endpoint); + + function getbase(url) + { + var l = document.createElement("a"); + l.href = url; + if (l.protocol && l.host) + return l.protocol + "//" + l.host; + else + ADL.XAPIWrapper.log("Couldn't create base url from endpoint: " + this.lrs.endpoint); + } + + function updateAuth(obj, username, password){ + obj.auth = "Basic " + toBase64(username + ":" + password); + } + + if (verifyxapiversion && testConfig.call(this)) + { + window.ADL.XHR_request(this.lrs, this.lrs.endpoint+"about", "GET", null, null, + function(r){ + if(r.status == 200) + { + try + { + var lrsabout = JSON.parse(r.response); + var versionOK = false; + for (var idx in lrsabout.version) + { + if(lrsabout.version[idx] == ADL.XAPIWrapper.xapiVersion) + { + versionOK = true; + break; + } + } + if (!versionOK) + { + ADL.XAPIWrapper.log("The lrs version [" + lrsabout.version +"]"+ + " does not match this wrapper's XAPI version [" + ADL.XAPIWrapper.xapiVersion + "]"); + } + } + catch(e) + { + ADL.XAPIWrapper.log("The response was not an about object") + } + } + else + { + ADL.XAPIWrapper.log("The request to get information about the LRS failed: " + r); + } + }); + } + + this.searchParams = function(){ + var sp = {"format" : "exact"}; + return sp; + }; + + this.hash = function(tohash){ + if (!tohash) return null; + try + { + return toSHA1(tohash); + } + catch(e) + { + ADL.XAPIWrapper.log("Error trying to hash -- " + e); + return null; + } + }; + + this.changeConfig = function(config){ + try + { + ADL.XAPIWrapper.log("updating lrs object with new configuration"); + this.lrs = mergeRecursive(this.lrs, config); + if (config.user && config.password) + this.updateAuth(this.lrs, config.user, config.password); + this.base = getbase(this.lrs.endpoint); + } + catch(e) + { + ADL.XAPIWrapper.log("error while changing configuration -- " + e); + } + }; + + this.updateAuth = updateAuth; + }; + + // This wrapper is based on the Experience API Spec version: + XAPIWrapper.prototype.xapiVersion = "1.0.1"; + + /* + * Adds info from the lrs object to the statement, if available. + * These values could be initialized from the Config object or from the url query string. + * @param {object} stmt the statement object + */ + XAPIWrapper.prototype.prepareStatement = function(stmt) + { + if(stmt.actor === undefined){ + stmt.actor = JSON.parse(this.lrs.actor); + } + else if(typeof stmt.actor === "string") { + stmt.actor = JSON.parse(stmt.actor); + } + if (this.lrs.grouping || + this.lrs.registration || + this.lrs.activity_platform) { + if (!stmt.context) { + stmt.context = {}; + } + } + + if (this.lrs.grouping) { + if (!stmt.context.contextActivities) { + stmt.context.contextActivities = {}; + } + stmt.context.contextActivities.grouping = [{ id : this.lrs.grouping }]; + } + if (this.lrs.registration) { + stmt.context.registration = this.lrs.registration; + } + if (this.lrs.activity_platform) { + stmt.context.platform = this.lrs.activity_platform; + } + }; + + // tests the configuration of the lrs object + XAPIWrapper.prototype.testConfig = testConfig; + + // writes to the console if available + XAPIWrapper.prototype.log = log; + + /* + * Send a single statement to the LRS. Makes a Javascript object + * with the statement id as 'id' available to the callback function. + * @param {object} stmt statement object to send + * @param {function} [callback] function to be called after the LRS responds + * to this request (makes the call asynchronous) + * the function will be passed the XMLHttpRequest object + * and an object with an id property assigned the id + * of the statement + * @return {object} object containing xhr object and id of statement + * @example + * // Send Statement + * var stmt = {"actor" : {"mbox" : "mailto:tom@example.com"}, + * "verb" : {"id" : "http://adlnet.gov/expapi/verbs/answered", + * "display" : {"en-US" : "answered"}}, + * "object" : {"id" : "http://adlnet.gov/expapi/activities/question"}}; + * var resp_obj = ADL.XAPIWrapper.sendStatement(stmt); + * ADL.XAPIWrapper.log("[" + resp_obj.id + "]: " + resp_obj.xhr.status + " - " + resp_obj.xhr.statusText); + * >> [3e616d1c-5394-42dc-a3aa-29414f8f0dfe]: 204 - NO CONTENT + * + * // Send Statement with Callback + * var stmt = {"actor" : {"mbox" : "mailto:tom@example.com"}, + * "verb" : {"id" : "http://adlnet.gov/expapi/verbs/answered", + * "display" : {"en-US" : "answered"}}, + * "object" : {"id" : "http://adlnet.gov/expapi/activities/question"}}; + * ADL.XAPIWrapper.sendStatement(stmt, function(resp, obj){ + * ADL.XAPIWrapper.log("[" + obj.id + "]: " + resp.status + " - " + resp.statusText);}); + * >> [4edfe763-8b84-41f1-a355-78b7601a6fe8]: 204 - NO CONTENT + */ + XAPIWrapper.prototype.sendStatement = function(stmt, callback) + { + return; + }; + + /* + * Send a list of statements to the LRS. + * @param {array} stmtArray the list of statement objects to send + * @param {function} [callback] function to be called after the LRS responds + * to this request (makes the call asynchronous) + * the function will be passed the XMLHttpRequest object + * @return {object} xhr response object + * @example + * var stmt = {"actor" : {"mbox" : "mailto:tom@example.com"}, + * "verb" : {"id" : "http://adlnet.gov/expapi/verbs/answered", + * "display" : {"en-US" : "answered"}}, + * "object" : {"id" : "http://adlnet.gov/expapi/activities/question"}}; + * var resp_obj = ADL.XAPIWrapper.sendStatement(stmt); + * ADL.XAPIWrapper.getStatements({"statementId":resp_obj.id}); + * >> {"version": "1.0.0", + * "timestamp": "2013-09-09 21:36:40.185841+00:00", + * "object": {"id": "http://adlnet.gov/expapi/activities/question", "objectType": "Activity"}, + * "actor": {"mbox": "mailto:tom@example.com", "name": "tom creighton", "objectType": "Agent"}, + * "stored": "2013-09-09 21:36:40.186124+00:00", + * "verb": {"id": "http://adlnet.gov/expapi/verbs/answered", "display": {"en-US": "answered"}}, + * "authority": {"mbox": "mailto:tom@adlnet.gov", "name": "tom", "objectType": "Agent"}, + * "context": {"registration": "51a6f860-1997-11e3-8ffd-0800200c9a66"}, + * "id": "ea9c1d01-0606-4ec7-8e5d-20f87b1211ed"} + */ + XAPIWrapper.prototype.sendStatements = function(stmtArray, callback) + { + return; + }; + + /* + * Get statement(s) based on the searchparams or more url. + * @param {object} searchparams an ADL.XAPIWrapper.searchParams object of + * key(search parameter)-value(parameter value) pairs. + * Example: + * var myparams = ADL.XAPIWrapper.searchParams(); + * myparams['verb'] = ADL.verbs.completed.id; + * var completedStmts = ADL.XAPIWrapper.getStatements(myparams); + * @param {string} more the more url found in the StatementResults object, if there are more + * statements available based on your get statements request. Pass the + * more url as this parameter to retrieve those statements. + * @param {function} [callback] - function to be called after the LRS responds + * to this request (makes the call asynchronous) + * the function will be passed the XMLHttpRequest object + * @return {object} xhr response object or null if 404 + * @example + * var ret = ADL.XAPIWrapper.getStatements(); + * if (ret) + * ADL.XAPIWrapper.log(ret.statements); + * + * >> + */ + XAPIWrapper.prototype.getStatements = function(searchparams, more, callback) + { + if (this.testConfig()) + { + var url = this.lrs.endpoint + "statements"; + if (more) + { + url = this.base + more; + } + else + { + var urlparams = new Array(); + + for (s in searchparams) + { + if (s == "until" || s == "since") { + var d = new Date(searchparams[s]); + urlparams.push(s + "=" + encodeURIComponent(d.toISOString())); + } else { + urlparams.push(s + "=" + encodeURIComponent(searchparams[s])); + } + } + if (urlparams.length > 0) + url = url + "?" + urlparams.join("&"); + } + + var res = ADL.XHR_request(this.lrs,url, "GET", null, this.lrs.auth, callback); + if(res === undefined || res.status == 404) + { + return null + } + + try + { + return JSON.parse(res.response); + } + catch(e) + { + return res.response; + } + } + }; + + /* + * Gets the Activity object from the LRS. + * @param {string} activityid the id of the Activity to get + * @param {function} [callback] function to be called after the LRS responds + * to this request (makes the call asynchronous) + * the function will be passed the XMLHttpRequest object + * @return {object} xhr response object or null if 404 + * @example + * var res = ADL.XAPIWrapper.getActivities("http://adlnet.gov/expapi/activities/question"); + * ADL.XAPIWrapper.log(res); + * >> + */ + XAPIWrapper.prototype.getActivities = function(activityid, callback) + { + return; + }; + + /* + * Store activity state in the LRS + * @param {string} activityid the id of the Activity this state is about + * @param {object} agent the agent this Activity state is related to + * @param {string} stateid the id you want associated with this state + * @param {string} [registration] the registraton id associated with this state + * @param {string} stateval the state + * @param {string} [matchHash] the hash of the state to replace or * to replace any + * @param {string} [noneMatchHash] the hash of the current state or * to indicate no previous state + * @param {function} [callback] function to be called after the LRS responds + * to this request (makes the call asynchronous) + * the function will be passed the XMLHttpRequest object + * @return {boolean} false if no activity state is included + * @example + * var stateval = {"info":"the state info"}; + * ADL.XAPIWrapper.sendState("http://adlnet.gov/expapi/activities/question", + * {"mbox":"mailto:tom@example.com"}, + * "questionstate", null, stateval); + */ + XAPIWrapper.prototype.sendState = function(activityid, agent, stateid, registration, stateval, matchHash, noneMatchHash, callback) + { + return; + }; + + /* + * Get activity state from the LRS + * @param {string} activityid the id of the Activity this state is about + * @param {object} agent the agent this Activity state is related to + * @param {string} [stateid] the id of the state, if not included, the response will be a list of stateids + * associated with the activity and agent) + * @param {string} [registration] the registraton id associated with this state + * @param {object} [since] date object or date string telling the LRS to return objects newer than the date supplied + * @param {function} [callback] function to be called after the LRS responds + * to this request (makes the call asynchronous) + * the function will be passed the XMLHttpRequest object + * @return {object} xhr response object or null if 404 + * @example + * ADL.XAPIWrapper.getState("http://adlnet.gov/expapi/activities/question", + * {"mbox":"mailto:tom@example.com"}, "questionstate"); + * >> {info: "the state info"} + */ + XAPIWrapper.prototype.getState = function(activityid, agent, stateid, registration, since, callback) + { + return; + }; + + /* + * Delete activity state in the LRS + * @param {string} activityid the id of the Activity this state is about + * @param {object} agent the agent this Activity state is related to + * @param {string} stateid the id you want associated with this state + * @param {string} [registration] the registraton id associated with this state + * @param {string} [matchHash] the hash of the state to replace or * to replace any + * @param {string} [noneMatchHash] the hash of the current state or * to indicate no previous state + * @param {string} [callback] function to be called after the LRS responds + * to this request (makes the call asynchronous) + * the function will be passed the XMLHttpRequest object + * @return {object} xhr response object or null if 404 + * @example + * var stateval = {"info":"the state info"}; + * ADL.XAPIWrapper.sendState("http://adlnet.gov/expapi/activities/question", + * {"mbox":"mailto:tom@example.com"}, + * "questionstate", null, stateval); + * ADL.XAPIWrapper.getState("http://adlnet.gov/expapi/activities/question", + * {"mbox":"mailto:tom@example.com"}, "questionstate"); + * >> {info: "the state info"} + * + * ADL.XAPIWrapper.deleteState("http://adlnet.gov/expapi/activities/question", + * {"mbox":"mailto:tom@example.com"}, "questionstate"); + * >> XMLHttpRequest {statusText: "NO CONTENT", status: 204, response: "", responseType: "", responseXML: null…} + * + * ADL.XAPIWrapper.getState("http://adlnet.gov/expapi/activities/question", + * {"mbox":"mailto:tom@example.com"}, "questionstate"); + * >> 404 + */ + XAPIWrapper.prototype.deleteState = function(activityid, agent, stateid, registration, matchHash, noneMatchHash, callback) + { + return; + }; + + /* + * Store activity profile in the LRS + * @param {string} activityid the id of the Activity this profile is about + * @param {string} profileid the id you want associated with this profile + * @param {string} profileval the profile + * @param {string} [matchHash] the hash of the profile to replace or * to replace any + * @param {string} [noneMatchHash] the hash of the current profile or * to indicate no previous profile + * @param {string} [callback] function to be called after the LRS responds + * to this request (makes the call asynchronous) + * the function will be passed the XMLHttpRequest object + * @return {bolean} false if no activity profile is included + * @example + * var profile = {"info":"the profile"}; + * ADL.XAPIWrapper.sendActivityProfile("http://adlnet.gov/expapi/activities/question", + * "actprofile", profile, null, "*"); + */ + XAPIWrapper.prototype.sendActivityProfile = function(activityid, profileid, profileval, matchHash, noneMatchHash, callback) + { + return; + }; + + /* + * Get activity profile from the LRS + * @param {string} activityid the id of the Activity this profile is about + * @param {string} [profileid] the id of the profile, if not included, the response will be a list of profileids + * associated with the activity + * @param {object} [since] date object or date string telling the LRS to return objects newer than the date supplied + * @param {function [callback] function to be called after the LRS responds + * to this request (makes the call asynchronous) + * the function will be passed the XMLHttpRequest object + * @return {object} xhr response object or null if 404 + * @example + * ADL.XAPIWrapper.getActivityProfile("http://adlnet.gov/expapi/activities/question", + * "actprofile", null, + * function(r){ADL.XAPIWrapper.log(JSON.parse(r.response));}); + * >> {info: "the profile"} + */ + XAPIWrapper.prototype.getActivityProfile = function(activityid, profileid, since, callback) + { + return; + }; + + /* + * Delete activity profile in the LRS + * @param {string} activityid the id of the Activity this profile is about + * @param {string} profileid the id you want associated with this profile + * @param {string} [matchHash] the hash of the profile to replace or * to replace any + * @param {string} [noneMatchHash] the hash of the current profile or * to indicate no previous profile + * @param {string} [callback] function to be called after the LRS responds + * to this request (makes the call asynchronous) + * the function will be passed the XMLHttpRequest object + * @return {object} xhr response object or null if 404 + * @example + * ADL.XAPIWrapper.deleteActivityProfile("http://adlnet.gov/expapi/activities/question", + * "actprofile"); + * >> XMLHttpRequest {statusText: "NO CONTENT", status: 204, response: "", responseType: "", responseXML: null…} + */ + XAPIWrapper.prototype.deleteActivityProfile = function(activityid, profileid, matchHash, noneMatchHash, callback) + { + return; + }; + + /* + * Gets the Person object from the LRS based on an agent object. + * The Person object may contain more information about an agent. + * See the xAPI Spec for details. + * @param {object} agent the agent object to get a Person + * @param {function [callback] function to be called after the LRS responds + * to this request (makes the call asynchronous) + * the function will be passed the XMLHttpRequest object + * @return {object} xhr response object or null if 404 + * @example + * var res = ADL.XAPIWrapper.getAgents({"mbox":"mailto:tom@example.com"}); + * ADL.XAPIWrapper.log(res); + * >> + */ + XAPIWrapper.prototype.getAgents = function(agent, callback) + { + return; + }; + + /* + * Store agent profile in the LRS + * @param {object} agent the agent this profile is related to + * @param {string} profileid the id you want associated with this profile + * @param {string} profileval the profile + * @param {string} [matchHash] the hash of the profile to replace or * to replace any + * @param {string} [noneMatchHash] the hash of the current profile or * to indicate no previous profile + * @param {string} [callback] function to be called after the LRS responds + * to this request (makes the call asynchronous) + * the function will be passed the XMLHttpRequest object + * @return {object} false if no agent profile is included + * @example + * var profile = {"info":"the agent profile"}; + * ADL.XAPIWrapper.sendAgentProfile({"mbox":"mailto:tom@example.com"}, + * "agentprofile", profile, null, "*"); + */ + XAPIWrapper.prototype.sendAgentProfile = function(agent, profileid, profileval, matchHash, noneMatchHash, callback) + { + return; + }; + + /* + * Get agnet profile from the LRS + * @param {object} agent the agent associated with this profile + * @param {string} [profileid] the id of the profile, if not included, the response will be a list of profileids + * associated with the agent + * @param {object} [since] date object or date string telling the LRS to return objects newer than the date supplied + * @param {function} [callback] function to be called after the LRS responds + * to this request (makes the call asynchronous) + * the function will be passed the XMLHttpRequest object + * @return {object} xhr response object or null if 404 + * @example + * ADL.XAPIWrapper.getAgentProfile({"mbox":"mailto:tom@example.com"}, + * "agentprofile", null, + * function(r){ADL.XAPIWrapper.log(JSON.parse(r.response));}); + * >> {info: "the agent profile"} + */ + XAPIWrapper.prototype.getAgentProfile = function(agent, profileid, since, callback) + { + return; + }; + + /* + * Delete agent profile in the LRS + * @param {oject} agent the id of the Agent this profile is about + * @param {string} profileid the id you want associated with this profile + * @param {string} [matchHash] the hash of the profile to replace or * to replace any + * @param {string} [noneMatchHash] the hash of the current profile or * to indicate no previous profile + * @param {string} [callback] function to be called after the LRS responds + * to this request (makes the call asynchronous) + * the function will be passed the XMLHttpRequest object + * @return {object} xhr response object or null if 404 + * @example + * ADL.XAPIWrapper.deleteAgentProfile({"mbox":"mailto:tom@example.com"}, + * "agentprofile"); + * >> XMLHttpRequest {statusText: "NO CONTENT", status: 204, response: "", responseType: "", responseXML: null…} + */ + XAPIWrapper.prototype.deleteAgentProfile = function(agent, profileid, matchHash, noneMatchHash, callback) + { + return; + }; + + /* + * Tests the configuration of the lrs object + */ + function testConfig() + { + try + { + return this.lrs.endpoint != undefined && this.lrs.endpoint != ""; + } + catch(e) + { + return false + } + } + + // outputs the message to the console if available + function log(message) + { + if (!log.debug) return false; + try + { + console.log(message); + return true; + } + catch(e){return false;} + } + + // merges two object + function mergeRecursive(obj1, obj2) + { + for (var p in obj2) + { + var prop = obj2[p]; + log(p + " : " + prop); + try + { + // Property in destination object set; update its value. + if ( obj2[p].constructor==Object ) + { + obj1[p] = mergeRecursive(obj1[p], obj2[p]); + + } + else + { + if (obj1 == undefined) + { + obj1 = new Object(); + } + obj1[p] = obj2[p]; + } + } + catch(e) + { + if (obj1 == undefined) + { + obj1 = new Object(); + } + // Property in destination object not set; create it and set its value. + obj1[p] = obj2[p]; + } + } + + return obj1; + } + + // iniitializes an lrs object with settings from + // a config file and from the url query string + function getLRSObject(config) + { + var lrsProps = ["endpoint","auth","actor","registration","activity_id", "grouping", "activity_platform"]; + var lrs = new Object(); + var qsVars, prop; + + qsVars = parseQueryString(); + if (qsVars !== undefined && Object.keys(qsVars).length !== 0) { + for (var i = 0; i 0){ + formData.push(newUrl.substr(qsIndex+1)); + newUrl = newUrl.substr(0, qsIndex); + } + + //Method has to go on querystring, and nothing else + newUrl = newUrl + '?method=' + method; + + //Headers + if(headers !== null){ + for(var headerName in headers){ + formData.push(headerName + "=" + encodeURIComponent(headers[headerName])); + } + } + + //The original data is repackaged as "content" form var + if(data !== null){ + formData.push('content=' + encodeURIComponent(data)); + } + + return { + "method":"POST", + "url":newUrl, + "headers":{}, + "data":formData.join("&") + }; + } + + /*! + Excerpt from: Math.uuid.js (v1.4) + http://www.broofa.com + mailto:robert@broofa.com + Copyright (c) 2010 Robert Kieffer + Dual licensed under the MIT and GPL licenses. + */ + ADL.ruuid = function() + { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { + var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8); + return v.toString(16); + }); + }; + + /* + * dateFromISOString + * parses an ISO string into a date object + * isostr - the ISO string + */ + ADL.dateFromISOString = function(isostr) + { + var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" + + "([T| ]([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?" + + "(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?"; + var d = isostr.match(new RegExp(regexp)); + + var offset = 0; + var date = new Date(d[1], 0, 1); + + if (d[3]) { date.setMonth(d[3] - 1); } + if (d[5]) { date.setDate(d[5]); } + if (d[7]) { date.setHours(d[7]); } + if (d[8]) { date.setMinutes(d[8]); } + if (d[10]) { date.setSeconds(d[10]); } + if (d[12]) { date.setMilliseconds(Number("0." + d[12]) * 1000); } + if (d[14]) { + offset = (Number(d[16]) * 60) + Number(d[17]); + offset *= ((d[15] == '-') ? 1 : -1); + } + + offset -= date.getTimezoneOffset(); + time = (Number(date) + (offset * 60 * 1000)); + + var dateToReturn = new Date(); + dateToReturn.setTime(Number(time)); + return dateToReturn; + }; + + // Synchronous if callback is not provided (not recommended) + /* + * makes a request to a server (if possible, use functions provided in XAPIWrapper) + * @param {string} lrs the lrs connection info, such as endpoint, auth, etc + * @param {string} url the url of this request + * @param {string} method the http request method + * @param {string} data the payload + * @param {string} auth the value for the Authorization header + * @param {function} callback function to be called after the LRS responds + * to this request (makes the call asynchronous) + * @param {object} [callbackargs] additional javascript object to be passed to the callback function + * @param {boolean} ignore404 allow page not found errors to pass + * @param {object} extraHeaders other header key-values to be added to this request + * @return {object} xhr response object + */ + ADL.XHR_request = function(lrs, url, method, data, auth, callback, callbackargs, ignore404, extraHeaders) + { + var arrstmts = []; + + var urlparts = url.split('/'); + var index = urlparts[urlparts.length - 1]; + + var keys = Object.keys(ADL.stmts); + var numstmts = keys.length; + var cutoff = 4; //only send 4 statements at a time + //index will either be zero or where to start with more statements + if (index == "statements") + { + index = 0; + } + else + { + index = parseInt(index); + } + //if doling out our ususal size block of statments would exceed the //amount of statements that we have, then adjust the cutoff + //and send out what's left + if (cutoff > (numstmts - index)) + { + cutoff = numstmts - index; + } + //make a mini array of the keys we want to return + var thesekeys = keys.slice(index, index + cutoff); + + for (var k in thesekeys) + { + arrstmts.push(ADL.stmts[thesekeys[k]]); + } + //assume there's no more statements, if there are more, + //then return the next index number + var morestmts = ""; + if ((index + cutoff) < numstmts) + { + morestmts = "/" + (index + cutoff); + } + //make a response object, and make that a string + var response = { + statements: arrstmts, + more: morestmts}; + response = JSON.stringify(response); + + callback({response}); + }; + + /* + * Holder for custom global error callback + * @param {object} xhr xhr object or null + * @param {string} method XMLHttpRequest request method + * @param {string} url full endpoint url + * @example + * ADL.xhrRequestOnError = function(xhr, method, url, callback, callbackargs) { + * console.log(xhr); + * alert(xhr.status + " " + xhr.statusText + ": " + xhr.response); + * }; + */ + ADL.xhrRequestOnError = function(xhr, method, url, callback, callbackargs){}; + + ADL.XAPIWrapper = new XAPIWrapper(Config, false); +}(window.ADL = window.ADL || {})); diff --git a/test/testUtil.html b/test/testUtil.html new file mode 100644 index 0000000..28850e2 --- /dev/null +++ b/test/testUtil.html @@ -0,0 +1,50 @@ + + + + + Mocha Tests + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + diff --git a/test/tests/test.util.js b/test/tests/test.util.js new file mode 100644 index 0000000..eebae11 --- /dev/null +++ b/test/tests/test.util.js @@ -0,0 +1,262 @@ +after(function () { + //nothing in here +}); + +describe('testing xAPI utilities', function () { + + var util, s1, s2, s3, s4, s5, s6, onBrowser, should, stmts; + + before(function () { + + onBrowser = false; + if (typeof window !== 'undefined') { + util = ADL.xapiutil; + onBrowser = true; + stmts = ADL.stmts; + } + else { + util = require('../../src/xapi-util').xapiutil; + should = require('should'); + stmts = require('../../examples/stmtBank.js').stmts; + } + + s1 = {"actor":{"mbox":"mailto:tom@tom.com", "openid":"openid", "mbox_sha1sum":"mbox_sha1sum", "account":"wrapperTesting"}, "verb":{"id":"http://verb.com/do1"}, "object":{"id":"http://from.tom/act1", "objectType":"StatementRef", "definition":{"name":{"en-US": "soccer", "fr": "football", "de": "foossball"}}}}; + + s2 = {"actor":{"openid":"openid", "mbox_sha1sum":"mbox_sha1sum", "account":"wrapperTesting", "name":"joe"}, "verb":{"id":"http://verb.com/do2", "display": {"fr": "recommander", "de": "empfehlen", "es": "recomendar", "en": "recommend"}}, "object":{"objectType":"Agent", "mbox":"mailto:joe@mail.com"}}; + + s3 = {"actor":{"mbox_sha1sum":"randomstringthatmakesnosensembox_sha1sum", "account":"wrapperTesting"}, "verb":{"id":"http://verb.com/do3"}, "object":{"objectType":"Group", 'notid':"http://from.tom/act3", "member":["joe"], "name":"obiwan", "mbox_sha1sum":"randomstringthatmakesnosensembox_sha1sum"}}; + + s4 = {"actor":{ "account":{"homePage":'http://adlnet.gov/test', "name":"wrapperTesting"}}, "verb":{ "id":"http://verb.com/do4", "display":{ "en-US":"initialized" }}, "object":{ "notid":"http://from.tom/act4", "objectType":"SubStatement", "actor":{ "mbox_sha1sum":"randomstringthatmakesnosensembox_sha1sum", "account":"wrapperTesting"}, "verb":{ "id":"http://verb.com/do3"}, "object":{ "objectType":"Group", "notid":"http://from.tom/act3", "member":["joe"], "mbox_sha1sum":"randomstringthatmakesnosensembox_sha1sum"}}}; + + s5 = {"actor":{"member":["joe"], "objectType": "Group"}, "verb":{"id":"http://verb.com/do5"}, "object":{"id":"http://from.tom/act5"}}; + + s6 = {"actor":{"some":"thing else"}, "verb":{"id":"http://verb.com/do6", "display":{"fr": "établi", "de": "etabliert"}}, "object":{"some":'thing else'}}; + }); + + + describe('test getLang', function () { + //tests relies on environment settings being 'en-US' + //failing this test does not necessarily mean that the code is bad, change "en-US" to match your proper environment setting + it('should get the language from the browser or node', function () { + (util.getLang()).should.eql("en-US"); + }); + }); + + describe('test getLangVal', function () { + it('should get an object definition name', function () { + (util.getLangVal(s1.object.definition.name)).should.eql("soccer"); + }); + it('should get a verb display', function () { + (util.getLangVal(s4.verb.display)).should.eql("initialized"); + }); + it('should get the en if the en-US is not available', function () { + (util.getLangVal(s2.verb.display)).should.eql("recommend"); + }); + it('should return the first display option if language code does not match any of the keys', function () { + ("undefined").should.eql(typeof util.getLangVal(s6.verb.display)); + }); + it('should throw out junk', function () { + ("undefined").should.eql(typeof util.getLangVal(s5.actor)); + ("undefined").should.eql(typeof util.getLangVal(s5.verb)); + ("undefined").should.eql(typeof util.getLangVal(s5.object)); + ("undefined").should.eql(typeof util.getLangVal(s5)); + }); + it('should quit if we pass in nothing to it', function () { + ("undefined").should.eql(typeof util.getLangVal()); + }); + it('should get the proper display if given a proper dictionary even a couple levels deep', function () { + (util.getLangVal(stmts['Object-Sub-Statement-with-StatementRef'].object.verb.display)).should.eql(stmts['Object-Sub-Statement-with-StatementRef'].object.verb.display.en); + }); + }); + + describe('test getMoreStatements', function () { + if (typeof window !== 'undefined') + { + it('should test getMoreStatements in the browser', function () { + (util.getMoreStatements(3, function (stmts) { + stmts.length.should.eql(16); + Array.isArray(stmts).should.eql(true); + stmts.should.be.type('object'); + util.getLang().should.eql("en-US"); + util.getActorId(stmts[0].actor).should.eql(ADL.stmts["Base-Statement"].actor.mbox); + util.getVerbDisplay(stmts[7].verb).should.eql(ADL.stmts["Verb-User-Defined"].verb.display['en-US']); + util.getObjectType(stmts[10].object).should.eql(ADL.stmts["Object-Agent"].object.objectType); + })) + }); + it('should handle only a single request with no additional calls', function () { + (util.getMoreStatements(0, function (stmts) { + stmts.length.should.eql(4); + Array.isArray(stmts).should.eql(true); + util.getActorIdString(stmts[0].actor).should.eql(ADL.stmts['Base-Statement'].actor.mbox); + util.getVerbDisplay(stmts[3].verb).should.eql(ADL.stmts["Actor-Anon-Group"].verb.display['en-US']); + util.getObjectIdString(stmts[2].object).should.eql(ADL.stmts["Actor-Id-Group"].object.id); + })); + }); + it('should handle only a single additional call', function () { + (util.getMoreStatements(1, function (stmts) { + stmts.length.should.eql(8); + Array.isArray(stmts).should.eql(true); + util.getActorIdString(stmts[0].actor).should.eql(ADL.stmts['Base-Statement'].actor.mbox); + util.getVerbDisplay(stmts[7].verb).should.eql(ADL.stmts["Verb-User-Defined"].verb.display['en-US']); + util.getObjectIdString(stmts[4].object).should.eql(ADL.stmts["Actor-Mbox"].object.id); + })); + }); + it('should handle a request which overreaches the available statements', function () { + (util.getMoreStatements(100, function (stmts) { + stmts.length.should.eql(Object.keys(ADL.stmts).length); + Array.isArray(stmts).should.eql(true); + util.getActorIdString(stmts[0].actor).should.eql(ADL.stmts['Base-Statement'].actor.mbox); + util.getVerbDisplay(stmts[15].verb).should.eql(ADL.stmts["Result"].verb.display['en-US']); + util.getObjectType(stmts[12].object).should.eql(ADL.stmts["Object-StatementRef"].object.objectType); + })); + }); + } + }); + + describe('test getActorId', function () { + it('should get the mailbox of the actor', function () { + (util.getActorId(s1.actor)).should.eql(s1.actor.mbox); + }); + it('should get the openid of the actor', function () { + (util.getActorId(s2.actor)).should.eql(s2.actor.openid); + }); + it('should get the mailbox sha1sum of the actor', function () { + (util.getActorId(s3.actor)).should.eql(s3.actor.mbox_sha1sum); + }); + it('should get the account of the actor', function () { + (util.getActorId(s4.actor)).should.eql(s4.actor.account); + }); + it('should get the account of an identified group', function () { + (util.getActorId(stmts["Actor-Id-Group"].actor)).should.eql(stmts["Actor-Id-Group"].actor.account); + }); + it('should be undefined for an anonymous group', function () { + ("undefined").should.eql(typeof util.getActorId(stmts["Actor-Anon-Group"].actor)); + ("undefined").should.eql(typeof util.getActorId(s5.actor)); + }); + }); + + describe('test getActorIdString', function () { + it('should return the mailbox of the actor', function () { + (util.getActorIdString(s1.actor)).should.be.String(); + (util.getActorIdString(s1.actor)).should.eql(s1.actor.mbox); + }); + it('should return the openid', function () { + (util.getActorIdString(s2.actor)).should.eql(s2.actor.openid); + }); + it('should return the sha1sum of the mailbox', function () { + (util.getActorIdString(s3.actor)).should.eql(s3.actor.mbox_sha1sum); + }); + it('should return a String of the account', function () { + (util.getActorIdString(s4.actor)).should.be.String(); + (util.getActorIdString(s4.actor)).should.eql(s4.actor.account.homePage + ":" + s4.actor.account.name); + }); + it('should return a String of the member', function () { + (util.getActorIdString(s5.actor)).should.be.String(); + (util.getActorIdString(s5.actor)).should.eql("Anon Group " + s5.actor.member); + }); + it ('should return unknown if nothing is present', function () { + (util.getActorIdString(s6.actor)).should.eql("unknown"); + }); + }); + + describe('test getActorDisplay', function () { + it('should get the actor name', function () { + (util.getActorDisplay(s2.actor)).should.eql(s2.actor.name); + }); + it('should get the actor id string', function () { + (util.getActorDisplay(s1.actor).should.eql(s1.actor.mbox)) + }); + }); + + describe('test getVerbDisplay', function () { + it('should return undefined with no verb', function () { + ("undefined").should.equal(typeof util.getVerbDisplay()); + }); + it('should get the verb in the proper language', function () { + (util.getVerbDisplay(s4.verb)).should.eql(s4.verb.display['en-US']); + }); + it('should get the verb id', function () { + (util.getVerbDisplay(s1.verb).should.eql(s1.verb.id)) + }) + }); + + describe('test getObjectType', function () { + it('should get the objectType when available', function () { + (util.getObjectType(s1.object)).should.eql(s1.object.objectType); + }); + it('should assume "Activity" if object id available', function () { + (util.getObjectType(s5.object).should.eql('Activity')); + }); + it('should assume "Agent" if neither id nor objectType available', function () { + (util.getObjectType(s6.object).should.eql('Agent')); + }); + }); + + describe('test getObjectId', function () { + it('should get the id', function () { + (util.getObjectId(s1.object)).should.eql(s1.object.id); + }); + it('should get the actor id, if no id and objectType is Agent', function () { + (util.getObjectId(s2.object)).should.eql(s2.object.mbox); + }); + it('should get the actor id, if no id and objectType is Group', function () { + (util.getObjectId(s3.object)).should.eql(util.getActorId(s3.object)); + }); + it('should get the actor id, if Statement Ref', function () { + (util.getObjectId(stmts["Object-StatementRef"].object)).should.eql(stmts["Object-StatementRef"].object.id); + }); + it('should get the actor id, if Sub-Statement', function () { + ("undefined").should.eql(typeof util.getObjectId(stmts["Object-Sub-Statement"].object)); + }); + it('should return undefined, if malformed', function () { + ('undefined').should.eql(typeof util.getObjectId(s6.object)); + }); + }); + + describe('test getObjectIdString', function () { + it('should get the id', function () { + (util.getActorIdString(s1.object)).should.be.String(); + (util.getObjectIdString(s1.object)).should.eql(s1.object.id); + }); + it('should get the Actor Id String, if no id and type is Agent or Group', function () { + (util.getObjectIdString(s2.object)).should.be.String(); + (util.getObjectIdString(s2.object)).should.eql(s2.object.mbox); + }); + it('should get the Actor-Verb-Object String, if no id and type is SubStatement', function () { + (util.getObjectIdString(s4.object)).should.be.String(); + (util.getObjectIdString(s4.object)).should.eql(s3.actor.mbox_sha1sum + ":" + s3.verb.id + ":" + s3.object.mbox_sha1sum); + }); + it('should return unknown, if those do not work', function () { + ('unknown').should.eql(util.getObjectIdString(s6.object)); + }); + it('should return unknown, if you pass it junk', function () { + ("unknown").should.eql(util.getObjectIdString(stmts)); + ("unknown").should.eql(util.getObjectIdString('stmts')); + ("unknown").should.eql(util.getObjectIdString()); + }); + }); + + describe('test getObjectDisplay', function () { + it('should get the object definition name', function () { + (util.getObjectDisplay(s1.object)).should.eql(s1.object.definition.name[util.getLang()]); + }); + it('or should get the object name', function () { + (util.getObjectDisplay(s3.object)).should.eql(s3.object.name); + }); + it('or should get the object id', function () { + (util.getObjectDisplay(s5.object)).should.eql(s5.object.id); + }); + it('or should get the object actor id', function () { + (util.getObjectDisplay(s2.object)).should.eql(s2.object.mbox); + }); + it('or should get the Actor-Verb-Object String', function () { + (util.getObjectDisplay(s4.object)).should.eql(s3.actor.mbox_sha1sum + ":" + s3.verb.id + ":" + s3.object.mbox_sha1sum); + }); + it('should handle junk', function () { + ('unknown').should.eql(util.getObjectDisplay(s3)); + ('unknown').should.eql(util.getObjectDisplay()); + ('unknown').should.eql(util.getObjectDisplay('s3')); + }); + }); + +})