You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by sg...@apache.org on 2014/09/30 09:46:04 UTC

[18/38] CB-7666 Move stuff outside of windows subdir

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/f4e2ac6a/template/cordova/lib/build.js
----------------------------------------------------------------------
diff --git a/template/cordova/lib/build.js b/template/cordova/lib/build.js
new file mode 100644
index 0000000..5af4ba0
--- /dev/null
+++ b/template/cordova/lib/build.js
@@ -0,0 +1,191 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var Q     = require('Q'),
+    path  = require('path'),
+    nopt  = require('nopt'),
+    spawn = require('./spawn'),
+    utils = require('./utils'),
+    prepare = require('./prepare'),
+    MSBuildTools = require('./MSBuildTools'),
+    ConfigParser = require('./ConfigParser');
+
+// Platform project root folder
+var ROOT = path.join(__dirname, '..', '..');
+var projFiles = {
+    phone: 'CordovaApp.Phone.jsproj',
+    win: 'CordovaApp.Windows.jsproj',
+    win80: 'CordovaApp.Windows80.jsproj'
+};
+// parsed nopt arguments
+var args;
+// build type (Release vs Debug)
+var buildType;
+// target chip architectures to build for
+var buildArchs;
+// MSBuild Tools available on this development machine
+var msbuild;
+
+// builds cordova-windows application with parameters provided.
+// See 'help' function for args list
+module.exports.run = function run (argv) {
+    if (!utils.isCordovaProject(ROOT)){
+        return Q.reject('Could not find project at ' + ROOT);
+    }
+
+    try {
+        // thows exception if something goes wrong
+        parseAndValidateArgs(argv);
+    } catch (error) {
+        return Q.reject(error);
+    }
+
+    // update platform as per configuration settings
+    prepare.applyPlatformConfig();
+
+    return MSBuildTools.findAvailableVersion().then(
+        function(msbuildTools) {
+            msbuild = msbuildTools;
+            console.log('MSBuildToolsPath: ' + msbuild.path);
+            return buildTargets();
+        });
+};
+
+// help/usage function
+module.exports.help = function help() {
+    console.log("");
+    console.log("Usage: build [ --debug | --release ] [--archs=\"<list of architectures...>\"] [--phone | --win]");
+    console.log("    --help    : Displays this dialog.");
+    console.log("    --debug   : Builds project in debug mode. (Default)");
+    console.log("    --release : Builds project in release mode.");
+    console.log("    -r        : Shortcut :: builds project in release mode.");
+    console.log("    --archs   : Builds project binaries for specific chip architectures (`anycpu`, `arm`, `x86`, `x64`).");
+    console.log("    --phone, --win");
+    console.log("              : Specifies, what type of project to build");
+    console.log("examples:");
+    console.log("    build ");
+    console.log("    build --debug");
+    console.log("    build --release");
+    console.log("    build --release --archs=\"arm x86\"");
+    console.log("");
+    process.exit(0);
+};
+
+function parseAndValidateArgs(argv) {
+    // parse and validate args
+    args = nopt({'debug': Boolean, 'release': Boolean, 'archs': [String],
+        'phone': Boolean, 'win': Boolean}, {'-r': '--release'}, argv);
+    // Validate args
+    if (args.debug && args.release) {
+        throw 'Only one of "debug"/"release" options should be specified';
+    }
+    if (args.phone && args.win) {
+        throw 'Only one of "phone"/"win" options should be specified';
+    }
+    
+    // get build options/defaults
+    buildType = args.release ? 'release' : 'debug';
+    buildArchs = args.archs ? args.archs.split(' ') : ['anycpu'];
+}
+
+function buildTargets() {
+
+    // filter targets to make sure they are supported on this development machine
+    var buildTargets = filterSupportedTargets(getBuildTargets(), msbuild);
+
+    var buildConfigs = [];
+
+    // collect all build configurations (pairs of project to build and target architecture)
+    buildTargets.forEach(function(buildTarget) {
+        buildArchs.forEach(function(buildArch) {
+            buildConfigs.push({target:buildTarget, arch: buildArch});
+        })
+    });
+
+    // run builds serially
+    return buildConfigs.reduce(function (promise, build) {
+         return promise.then(function () {
+            // support for "any cpu" specified with or without space
+            if (build.arch == 'any cpu') {
+                build.arch = 'anycpu';
+            }
+            // msbuild 4.0 requires .sln file, we can't build jsproj
+            if (msbuild.version == '4.0' && build.target == projFiles.win80) {
+                build.target = 'CordovaApp.vs2012.sln';
+            }
+            return msbuild.buildProject(path.join(ROOT, build.target), buildType,  build.arch);
+         });
+    }, Q()); 
+}
+
+function getBuildTargets() {
+    var config = new ConfigParser(path.join(ROOT, 'config.xml'));
+    var targets = [];
+    var noSwitches = !(args.phone || args.win);
+    // Windows
+    if (args.win || noSwitches) { // if --win or no arg
+        var windowsTargetVersion = config.getPreference('windows-target-version')
+        switch(windowsTargetVersion) {
+        case '8':
+        case '8.0':
+            targets.push(projFiles.win80);
+            break;
+        case '8.1':
+            targets.push(projFiles.win);
+            break;
+        default:
+            throw new Error('Unsupported windows-target-version value: ' + windowsTargetVersion)
+        }
+    }
+    // Windows Phone
+    if (args.phone || noSwitches) { // if --phone or no arg
+        var windowsPhoneTargetVersion = config.getPreference('windows-phone-target-version')
+        switch(windowsPhoneTargetVersion) {
+        case '8.1':
+            targets.push(projFiles.phone);
+            break;
+        default:
+            throw new Error('Unsupported windows-phone-target-version value: ' + windowsPhoneTargetVersion)
+        }
+    }
+    return targets;
+}
+
+function filterSupportedTargets (targets) {
+    if (!targets || targets.length == 0) {
+        console.warn("\r\nNo build targets are specified.");
+        return [];
+    }
+
+    if (msbuild.version != '4.0') {
+        return targets;
+    }
+
+    // MSBuild 4.0 does not support Windows 8.1 and Windows Phone 8.1
+    var supportedTargets = targets.filter(function(target) {
+        return target != projFiles.win && target != projFiles.phone;
+    });
+
+    // unsupported targets have been detected
+    if (supportedTargets.length != targets.length) {
+        console.warn("\r\nWarning. Windows 8.1 and Windows Phone 8.1 target platforms are not supported on this development machine and will be skipped.");
+        console.warn("Please install OS Windows 8.1 and Visual Studio 2013 Update2 in order to build for Windows 8.1 and Windows Phone 8.1.\r\n");
+    }
+    return supportedTargets;
+}

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/f4e2ac6a/template/cordova/lib/clean.js
----------------------------------------------------------------------
diff --git a/template/cordova/lib/clean.js b/template/cordova/lib/clean.js
new file mode 100644
index 0000000..edd40de
--- /dev/null
+++ b/template/cordova/lib/clean.js
@@ -0,0 +1,33 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var Q     = require('q'),
+    path  = require('path'),
+    shell = require('shelljs');
+
+var ROOT = path.join(__dirname, '..', '..');
+
+// cleans the project, removes AppPackages and build folders.
+module.exports.run = function (argv) {
+    var projectPath = ROOT;
+    ['AppPackages', 'build'].forEach(function(dir) {
+        shell.rm('-rf', path.join(projectPath, dir));
+    });
+    return Q.resolve();
+};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/f4e2ac6a/template/cordova/lib/exec.js
----------------------------------------------------------------------
diff --git a/template/cordova/lib/exec.js b/template/cordova/lib/exec.js
new file mode 100644
index 0000000..d71eda7
--- /dev/null
+++ b/template/cordova/lib/exec.js
@@ -0,0 +1,38 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var child_process = require('child_process'),
+    Q       = require('q');
+
+// Takes a command and optional current working directory.
+// Returns a promise that either resolves with the stdout, or
+// rejects with an error message and the stderr.
+module.exports = function(cmd, opt_cwd) {
+    var d = Q.defer();
+    try {
+        child_process.exec(cmd, {cwd: opt_cwd, maxBuffer: 1024000}, function(err, stdout, stderr) {
+            if (err) d.reject('Error executing "' + cmd + '": ' + stderr);
+            else d.resolve(stdout);
+        });
+    } catch(e) {
+        console.error('error caught: ' + e);
+        d.reject(e);
+    }
+    return d.promise;
+};

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/f4e2ac6a/template/cordova/lib/list-devices.bat
----------------------------------------------------------------------
diff --git a/template/cordova/lib/list-devices.bat b/template/cordova/lib/list-devices.bat
new file mode 100644
index 0000000..016fcfc
--- /dev/null
+++ b/template/cordova/lib/list-devices.bat
@@ -0,0 +1,25 @@
+:: Licensed to the Apache Software Foundation (ASF) under one
+:: or more contributor license agreements.  See the NOTICE file
+:: distributed with this work for additional information
+:: regarding copyright ownership.  The ASF licenses this file
+:: to you under the Apache License, Version 2.0 (the
+:: "License"); you may not use this file except in compliance
+:: with the License.  You may obtain a copy of the License at
+:: 
+:: http://www.apache.org/licenses/LICENSE-2.0
+:: 
+:: Unless required by applicable law or agreed to in writing,
+:: software distributed under the License is distributed on an
+:: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+:: KIND, either express or implied.  See the License for the
+:: specific language governing permissions and limitations
+:: under the License
+@ECHO OFF
+SET script_path="%~dp0package.js"
+IF EXIST %script_path% (
+        node -e "require('./%script_path%').listDevices().done(function(devices){console.log(devices)})"
+) ELSE (
+    ECHO.
+    ECHO ERROR: Could not find 'package' script in 'cordova/lib' folder, aborting...>&2
+    EXIT /B 1
+)

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/f4e2ac6a/template/cordova/lib/list-emulator-images.bat
----------------------------------------------------------------------
diff --git a/template/cordova/lib/list-emulator-images.bat b/template/cordova/lib/list-emulator-images.bat
new file mode 100644
index 0000000..a06f581
--- /dev/null
+++ b/template/cordova/lib/list-emulator-images.bat
@@ -0,0 +1,19 @@
+:: Licensed to the Apache Software Foundation (ASF) under one
+:: or more contributor license agreements.  See the NOTICE file
+:: distributed with this work for additional information
+:: regarding copyright ownership.  The ASF licenses this file
+:: to you under the Apache License, Version 2.0 (the
+:: "License"); you may not use this file except in compliance
+:: with the License.  You may obtain a copy of the License at
+:: 
+:: http://www.apache.org/licenses/LICENSE-2.0
+:: 
+:: Unless required by applicable law or agreed to in writing,
+:: software distributed under the License is distributed on an
+:: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+:: KIND, either express or implied.  See the License for the
+:: specific language governing permissions and limitations
+:: under the License
+@ECHO OFF
+ECHO Error! Windows 8 Cordova CLI tools do not support list-emulator-images currently.
+EXIT /B 1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/f4e2ac6a/template/cordova/lib/list-started-emulators.bat
----------------------------------------------------------------------
diff --git a/template/cordova/lib/list-started-emulators.bat b/template/cordova/lib/list-started-emulators.bat
new file mode 100644
index 0000000..e576c5e
--- /dev/null
+++ b/template/cordova/lib/list-started-emulators.bat
@@ -0,0 +1,19 @@
+:: Licensed to the Apache Software Foundation (ASF) under one
+:: or more contributor license agreements.  See the NOTICE file
+:: distributed with this work for additional information
+:: regarding copyright ownership.  The ASF licenses this file
+:: to you under the Apache License, Version 2.0 (the
+:: "License"); you may not use this file except in compliance
+:: with the License.  You may obtain a copy of the License at
+:: 
+:: http://www.apache.org/licenses/LICENSE-2.0
+:: 
+:: Unless required by applicable law or agreed to in writing,
+:: software distributed under the License is distributed on an
+:: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+:: KIND, either express or implied.  See the License for the
+:: specific language governing permissions and limitations
+:: under the License
+@ECHO OFF
+ECHO Error! Windows 8 Cordova CLI tools do not support list-started-emulators currently.
+EXIT /B 1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/f4e2ac6a/template/cordova/lib/package.js
----------------------------------------------------------------------
diff --git a/template/cordova/lib/package.js b/template/cordova/lib/package.js
new file mode 100644
index 0000000..ad609ed
--- /dev/null
+++ b/template/cordova/lib/package.js
@@ -0,0 +1,174 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var Q     = require('q'),
+    fs    = require('fs'),
+    path  = require('path'),
+    exec  = require('./exec'),
+    spawn = require('./spawn'),
+    utils = require('./utils');
+
+// returns folder that contains package with chip architecture,
+// build and project types specified by script parameters
+module.exports.getPackage = function (projectType, buildtype, buildArch) {
+    var appPackages = path.resolve(path.join(__dirname, '..', '..', 'AppPackages'));
+    // reject promise if apppackages folder doesn't exists
+    if (!fs.existsSync(appPackages)) {
+        return Q.reject('AppPackages doesn\'t exists');
+    }
+    // find out and resolve paths for all folders inside AppPackages
+    var pkgDirs = fs.readdirSync(appPackages).map(function(relative) {
+        // resolve path to folder
+        return path.join(appPackages, relative);
+    }).filter(function(pkgDir) {
+        // check that it is a directory
+        return fs.statSync(pkgDir).isDirectory();
+    });
+
+    for (var dir in pkgDirs) {
+        var packageFiles = fs.readdirSync(pkgDirs[dir]).filter(function(e) {
+            return e.match('.*.(appx|appxbundle)$');
+        });
+
+        for (var pkgFile in packageFiles) {
+            var packageFile = path.join(pkgDirs[dir], packageFiles[pkgFile]);
+            var pkgInfo = module.exports.getPackageFileInfo(packageFile);
+
+            if (pkgInfo && pkgInfo.type == projectType &&
+                pkgInfo.arch == buildArch && pkgInfo.buildtype == buildtype) {
+                // if package's properties are corresponds to properties provided
+                // resolve the promise with this package's info
+                return Q.resolve(pkgInfo);
+            }
+        }
+    }
+    // reject because seems that no corresponding packages found
+    return Q.reject('Package with specified parameters not found in AppPackages folder');
+};
+
+// returns package info object or null if it is not valid package
+module.exports.getPackageFileInfo = function (packageFile) {
+    var pkgName = path.basename(packageFile);
+    // CordovaApp.Windows_0.0.1.0_anycpu_debug.appx
+    // CordovaApp.Phone_0.0.1.0_x86_debug.appxbundle
+    var props = /.*\.(Phone|Windows|Windows80)_((?:\d\.)*\d)_(AnyCPU|x64|x86|ARM)(?:_(Debug))?.(appx|appxbundle)$/i.exec(pkgName);
+    if (props) {
+        return {type      : props[1].toLowerCase(),
+            arch      : props[3].toLowerCase(),
+            buildtype : props[4] ? props[4].toLowerCase() : "release",
+            file      : props[1].toLowerCase() != "phone" ?
+                path.join(packageFile, '..', 'Add-AppDevPackage.ps1') :
+                packageFile
+        };
+    }
+    return null;
+};
+
+// return package app ID fetched from appxmanifest
+// return rejected promise if appxmanifest not valid
+module.exports.getAppId = function (platformPath) {
+    var manifest = path.join(platformPath, 'package.phone.appxmanifest');
+    try {
+        return Q.resolve(/PhoneProductId="(.*?)"/gi.exec(fs.readFileSync(manifest, 'utf8'))[1]);
+    } catch (e) {
+        return Q.reject('Can\'t read appId from phone manifest' + e);
+    }
+};
+
+// return package name fetched from appxmanifest
+// return rejected promise if appxmanifest not valid
+module.exports.getPackageName = function (platformPath) {
+    var manifest = path.join(platformPath, 'package.windows.appxmanifest');
+    try {
+        return Q.resolve(/Application Id="(.*?)"/gi.exec(fs.readFileSync(manifest, 'utf8'))[1]);
+    } catch (e) {
+        return Q.reject('Can\'t read package name from manifest ' + e);
+    }
+};
+
+// returns one of available devices which name match with parovided string
+// return rejected promise if device with name specified not found
+module.exports.findDevice = function (target) {
+    target = target.toLowerCase();
+    return module.exports.listDevices().then(function(deviceList) {
+        for (var idx in deviceList){
+            if (deviceList[idx].toLowerCase() == target) {
+                return Q.resolve(idx);
+            }
+        }
+        return Q.reject('Specified device not found');
+    });
+};
+
+// returns array of available devices names
+module.exports.listDevices = function () {
+    return utils.getAppDeployUtils().then(function(appDeployUtils) {
+        return exec('"' + appDeployUtils + '" /enumeratedevices').then(function(output) {
+            return Q.resolve(output.split('\n').map(function(line) {
+                var match = /\s*(\d)+\s+(.*)/.exec(line);
+                return match && match[2];
+            }).filter(function (line) {
+                return line;
+            }));
+        });
+    });
+};
+
+// deploys specified phone package to device/emulator
+module.exports.deployToPhone = function (appxPath, deployTarget) {
+    var getTarget = deployTarget == "device" ? Q("de") :
+        deployTarget == "emulator" ? Q("xd") : module.exports.findDevice(deployTarget);
+
+    // /installlaunch option sometimes fails with 'Error: The parameter is incorrect.'
+    // so we use separate steps to /install and then /launch
+    return getTarget.then(function(target) {
+        return utils.getAppDeployUtils().then(function(appDeployUtils) {
+            console.log('Installing application');
+            return spawn(appDeployUtils, ['/install', appxPath, '/targetdevice:' + target]).then(function() {
+                // TODO: resolve AppId without specifying project root;
+                return module.exports.getAppId(path.join(__dirname, '..', '..'));
+            }).then(function(appId) {
+                console.log('Running application');
+                return spawn(appDeployUtils, ['/launch', appId, '/targetdevice:' + target]);
+            });
+        });
+    });
+};
+
+// deploys specified package to desktop
+module.exports.deployToDesktop = function (appxScript, deployTarget) {
+    if (deployTarget != "device" && deployTarget != "emulator") {
+        return Q.reject("Deploying desktop apps to specific target not supported");
+    }
+
+    return utils.getAppStoreUtils().then(function(appStoreUtils) {
+        return module.exports.getPackageName(path.join(__dirname, '..', '..')).then(function(pkgname) {
+            // uninstalls previous application instance (if exists)
+            console.log("Attempt to uninstall previous application version...");
+            return spawn('powershell', ['-ExecutionPolicy', 'RemoteSigned', 'Import-Module "' + appStoreUtils + '"; Uninstall-App ' + pkgname])
+            .then(function() {
+                console.log("Attempt to install application...");
+                return spawn('powershell', ['-ExecutionPolicy', 'RemoteSigned', 'Import-Module "' + appStoreUtils + '"; Install-App', utils.quote(appxScript)]);
+            }).then(function() {
+                console.log("Starting application...");
+                return spawn('powershell', ['-ExecutionPolicy', 'RemoteSigned', 'Import-Module "' + appStoreUtils + '"; Start-Locally', pkgname]);
+            });
+        });
+    });
+};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/f4e2ac6a/template/cordova/lib/prepare.js
----------------------------------------------------------------------
diff --git a/template/cordova/lib/prepare.js b/template/cordova/lib/prepare.js
new file mode 100644
index 0000000..5e3f533
--- /dev/null
+++ b/template/cordova/lib/prepare.js
@@ -0,0 +1,315 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var path  = require('path'),
+    fs  = require('fs'),
+    et = require('elementtree'),
+    shell = require('shelljs'),
+    ConfigParser = require('./ConfigParser');
+
+var ROOT = path.join(__dirname, '..', '..'),
+    accessRules;
+
+module.exports.applyPlatformConfig = function () {
+    console.log('Applying Platform Config...');
+
+    var config = new ConfigParser(path.join(ROOT, 'config.xml'));
+
+    accessRules = config.getAccessRules().filter(function(rule) {
+        if (rule.indexOf('https://') == 0 || rule == '*') {
+            return true;
+        } else {
+            console.log('Access rules must begin with "https://", the following rule will be ignored: ' + rule);
+        }
+        return false;
+    });
+
+    ['package.windows.appxmanifest', 'package.windows80.appxmanifest', 'package.phone.appxmanifest'].forEach(
+        function(manifestFile) {
+            updateManifestFile(config, path.join(ROOT, manifestFile));
+    })
+
+    copyImages(config);
+}
+
+function updateManifestFile (config, manifestPath) {
+
+    var contents = fs.readFileSync(manifestPath, 'utf-8');
+    if(contents) {
+        //Windows is the BOM. Skip the Byte Order Mark.
+        contents = contents.substring(contents.indexOf('<'));
+    };
+
+    var manifest =  new et.ElementTree(et.XML(contents));
+
+    applyCoreProperties(config, manifest);
+    // sort Capability elements as per CB-5350 Windows8 build fails due to invalid 'Capabilities' definition
+    sortCapabilities(manifest);
+    applyAccessRules(config, manifest);
+    applyBackgroundColor(config, manifest);
+
+    //Write out manifest
+    fs.writeFileSync(manifestPath, manifest.write({indent: 4}), 'utf-8');
+}
+
+function applyCoreProperties(config, manifest) {
+    var version = fixConfigVersion(config.version());
+    var name = config.name();
+    var pkgName = config.packageName();
+    var author = config.author();
+    var startPage = config.startPage();
+
+    if (!startPage) {
+        // If not specified, set default value
+        // http://cordova.apache.org/docs/en/edge/config_ref_index.md.html#The%20config.xml%20File
+        startPage = "index.html";
+    }
+
+    var identityNode = manifest.find('.//Identity');
+    if(!identityNode) {
+        throw new Error('Invalid manifest file (no <Identity> node): ' + manifestPath);
+    }
+    // Update identity name and version
+    pkgName && (identityNode.attrib.Name = pkgName);
+    version && (identityNode.attrib.Version = version);
+
+    // Update name (windows8 has it in the Application[@Id] and Application.VisualElements[@DisplayName])
+    var app = manifest.find('.//Application');
+    if(!app) {
+        throw new Error('Invalid manifest file (no <Application> node): ' + manifestPath);
+    }
+    if (pkgName) {
+        // 64 symbols restriction goes from manifest schema definition
+        // http://msdn.microsoft.com/en-us/library/windows/apps/br211415.aspx
+        var appId = pkgName.length <= 64 ? pkgName : pkgName.substr(0, 64);
+        app.attrib.Id = appId;
+    }
+    app.attrib.StartPage = 'www/' + startPage;
+
+    var visualElems = manifest.find('.//VisualElements') // windows 8.0
+        || manifest.find('.//m2:VisualElements') // windows 8.1
+        || manifest.find('.//m3:VisualElements'); // windows phone 8.1
+
+    if(!visualElems) {
+        throw new Error('Invalid manifest file (no <VisualElements> node): ' + manifestPath);
+    }
+    name && (visualElems.attrib.DisplayName = name);
+
+    // Update properties
+    var properties = manifest.find('.//Properties');
+    if (properties && properties.find) {
+        var displayNameElement = properties.find('.//DisplayName');
+        if (displayNameElement && name) {
+            displayNameElement.text = name;
+        }
+
+        var publisherNameElement = properties.find('.//PublisherDisplayName');
+        if (publisherNameElement && author) {
+            publisherNameElement.text = author;
+        }
+    }
+}
+
+// Adjust version number as per CB-5337 Windows8 build fails due to invalid app version
+function fixConfigVersion (version) {
+    if(version && version.match(/\.\d/g)) {
+        var numVersionComponents = version.match(/\.\d/g).length + 1;
+        while (numVersionComponents++ < 4) {
+            version += '.0';
+        }
+    }
+    return version;
+}
+
+function applyAccessRules (config, manifest) {
+    // Updates WhiteListing rules
+    //<ApplicationContentUriRules>
+    //    <Rule Match="https://www.example.com" Type="include"/>
+    //</ApplicationContentUriRules>
+    var appUriRulesRoot = manifest.find('.//Application'),
+        appUriRules = appUriRulesRoot.find('.//ApplicationContentUriRules');
+
+    if (appUriRules != null) {
+        appUriRulesRoot.remove(null, appUriRules);
+    }
+    // rules are not defined or allow any
+    if (accessRules.length == 0 || accessRules.indexOf('*') > -1) {
+        return;
+    } 
+
+    appUriRules = et.Element('ApplicationContentUriRules');
+    appUriRulesRoot.append(appUriRules);
+
+    accessRules.forEach(function(rule) {
+        var el = et.Element('Rule')
+        el.attrib.Match = rule;
+        el.attrib.Type = 'include';
+        appUriRules.append(el);
+    });
+}
+
+function sortCapabilities(manifest) {
+
+    // removes namespace prefix (m3:Capability -> Capability)
+    // this is required since elementtree returns qualified name with namespace
+    function extractLocalName(tag) {
+        return tag.split(':').pop(); // takes last part of string after ':'
+    }
+
+    var capabilitiesRoot = manifest.find('.//Capabilities'),
+        capabilities = capabilitiesRoot._children || [];
+    // to sort elements we remove them and then add again in the appropriate order
+    capabilities.forEach(function(elem) { // no .clear() method
+        capabilitiesRoot.remove(0, elem);
+        // CB-7601 we need local name w/o namespace prefix to sort capabilities correctly
+        elem.localName = extractLocalName(elem.tag);
+    });
+    capabilities.sort(function(a, b) {
+        return (a.localName > b.localName) ? 1: -1;
+    });
+    capabilities.forEach(function(elem) {
+        capabilitiesRoot.append(elem);
+    });
+}
+
+function copyImages(config) {
+    var platformRoot = ROOT;
+    // TODO find the way to detect whether command was triggered by CLI or not
+    var appRoot = path.join(platformRoot, '..', '..');
+
+    function copyImage(src, dest) {
+        src = path.join(appRoot, src),
+        dest = path.join(platformRoot, 'images', dest);
+        //console.log('Copying image from ' + src + ' to ' + dest);
+        shell.cp('-f', src, dest);
+    }
+
+    function copyMrtImage(src, dest) {
+        var srcDir = path.dirname(src),
+            srcExt = path.extname(src),
+            srcFileName = path.basename(src, srcExt);
+     
+        var destExt = path.extname(dest),
+            destFileName = path.basename(dest, destExt);
+
+        // all MRT images: logo.png, logo.scale-100.png, logo.scale-200.png, etc
+        var images = fs.readdirSync(srcDir).filter(function(e) { 
+            return e.match('^'+srcFileName + '(.scale-[0-9]+)?' + srcExt);
+        });
+        // warn if no images found
+        if (images.length == 0) {
+            console.log('No images found for target: ' + destFileName);
+            return;
+        }
+        // copy images with new name but keeping scale suffix
+        images.forEach(function(img) {
+            var scale = path.extname(path.basename(img, srcExt));
+            if (scale == '') {
+                scale = '.scale-100';
+            }
+            copyImage(path.join(srcDir, img), destFileName+scale+destExt);
+        });
+        
+    }
+
+    // Platform default images
+    var platformImages = [
+        {dest: 'Square150x150Logo.scale-100.png', width: 150, height: 150},
+        {dest: 'Square30x30Logo.scale-100.png', width: 30, height: 30},
+        {dest: 'StoreLogo.scale-100.png', width: 50, height: 50},
+        {dest: 'SplashScreen.scale-100.png', width: 620, height: 300},
+        // scaled images are specified here for backward compatibility only so we can find them by size
+        {dest: 'StoreLogo.scale-240.png', width: 120, height: 120},
+        {dest: 'Square44x44Logo.scale-240.png', width: 106, height: 106},
+        {dest: 'Square71x71Logo.scale-240.png', width: 170, height: 170},
+        {dest: 'Square70x70Logo.scale-100.png', width: 70, height: 70},
+        {dest: 'Square150x150Logo.scale-240.png', width: 360, height: 360},
+        {dest: 'Square310x310Logo.scale-100.png', width: 310, height: 310},
+        {dest: 'Wide310x150Logo.scale-100.png', width: 310, height: 150},
+        {dest: 'Wide310x150Logo.scale-240.png', width: 744, height: 360},
+        {dest: 'SplashScreenPhone.scale-240.png', width: 1152, height: 1920}
+    ];
+
+    function findPlatformImage(width, height) {
+        if (!width && !height){
+            // this could be default image, 
+            // Windows requires specific image dimension so we can't apply it
+            return null;
+        }
+        for (var idx in platformImages){
+            var res = platformImages[idx];
+            // If only one of width or height is not specified, use another parameter for comparation
+            // If both specified, compare both.
+            if ((!width || (width == res.width)) &&
+                (!height || (height == res.height))){
+                return res;
+            }
+        }
+        return null;
+    }
+
+    var images = config.getIcons().concat(config.getSplashScreens());
+
+    images.forEach(function (img) {
+        if (img.target) {
+            copyMrtImage(img.src, img.target + '.png');
+        } else {
+            // find target image by size
+            var targetImg = findPlatformImage (img.width, img.height);
+            if (targetImg) {
+                copyImage(img.src, targetImg.dest);
+            } else {
+                console.log('The following image is skipped due to unsupported size: ' + img.src);
+            }
+        }
+    });
+}
+
+function applyBackgroundColor (config, manifest) {
+
+    function refineColor(color) {
+        // return three-byte hexadecimal number preceded by "#" (required for Windows)
+        color = color.replace('0x', '').replace('#', '');
+        if (color.length == 3) {
+            color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2]
+        }
+        // alpha is not supported, so we remove it
+        if (color.length == 8) { // AArrggbb
+            color = color.slice(2);
+        }
+        return '#' + color;
+    }
+    // background color
+    var bgColor = config.getPreference('BackgroundColor');
+    if (bgColor) {
+        var visualElems = manifest.find('.//VisualElements') // windows 8.0
+            || manifest.find('.//m2:VisualElements') // windows 8.1
+            || manifest.find('.//m3:VisualElements'); // windows phone 8.1
+        visualElems.attrib.BackgroundColor = refineColor(bgColor);
+    }
+
+    // Splash Screen background color
+    bgColor = config.getPreference('SplashScreenBackgroundColor');
+    if (bgColor) {
+        var visualElems = manifest.find('.//SplashScreen') // windows 8.0
+            || manifest.find('.//m2:SplashScreen') // windows 8.1
+            || manifest.find('.//m3:SplashScreen'); // windows phone 8.1
+        visualElems.attrib.BackgroundColor = refineColor(bgColor);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/f4e2ac6a/template/cordova/lib/run.js
----------------------------------------------------------------------
diff --git a/template/cordova/lib/run.js b/template/cordova/lib/run.js
new file mode 100644
index 0000000..1bd1904
--- /dev/null
+++ b/template/cordova/lib/run.js
@@ -0,0 +1,112 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var Q = require('q'),
+    nopt  = require('nopt'),
+    path  = require('path'),
+    build = require('./build'),
+    utils = require('./utils'),
+    ConfigParser = require('./ConfigParser'),
+    packages = require('./package');
+
+var ROOT = path.join(__dirname, '..', '..');
+
+module.exports.run = function (argv) {
+    if (!utils.isCordovaProject(ROOT)){
+        return Q.reject("Could not find project at " + ROOT);
+    }
+
+    // parse args
+    var args  = nopt({"debug": Boolean, "release": Boolean, "nobuild": Boolean,
+        "device": Boolean, "emulator": Boolean, "target": String, "archs": String,
+        "phone": Boolean, "win": Boolean}, {"r" : "--release"}, argv);
+
+    // Validate args
+    if (args.debug && args.release) {
+        return Q.reject('Only one of "debug"/"release" options should be specified');
+    }
+    if ((args.device && args.emulator) || ((args.device || args.emulator) && args.target)) {
+        return Q.reject('Only one of "device"/"emulator"/"target" options should be specified');
+    }
+    if (args.phone && args.win) {
+        return Q.reject('Only one of "phone"/"win" options should be specified');
+    }
+
+    // Get build/deploy options
+    var buildType    = args.release ? "release" : "debug",
+        buildArchs   = args.archs ? args.archs.split(' ') : ["anycpu"],
+        projectType  = args.phone ? "phone" : "windows",
+        deployTarget = args.target ? args.target : args.device ? "device" : "emulator";
+
+    // for win switch we should correctly handle 8.0 and 8.1 version as per configuration
+    if (projectType == 'windows' && getWindowsTargetVersion() == '8.0') {
+        projectType = 'windows80'
+    }
+
+    // if --nobuild isn't specified then build app first
+    var buildPackages = args.nobuild ? Q() : build.run(argv);
+
+    return buildPackages.then(function () {
+        return packages.getPackage(projectType, buildType, buildArchs[0]);
+    }).then(function(pkg) {
+        console.log('\nDeploying ' + pkg.type + ' package to ' + deployTarget + ':\n' + pkg.file);
+        return pkg.type == "phone" ?
+            packages.deployToPhone(pkg.file, deployTarget) :
+            packages.deployToDesktop(pkg.file, deployTarget);
+    });
+};
+
+module.exports.help = function () {
+    console.log("\nUsage: run [ --device | --emulator | --target=<id> ] [ --debug | --release | --nobuild ]");
+    console.log("           [ --x86 | --x64 | --arm ] [--phone | --win]");
+    console.log("    --device      : Deploys and runs the project on the connected device.");
+    console.log("    --emulator    : Deploys and runs the project on an emulator.");
+    console.log("    --target=<id> : Deploys and runs the project on the specified target.");
+    console.log("    --debug       : Builds project in debug mode.");
+    console.log("    --release     : Builds project in release mode.");
+    console.log("    --nobuild     : Uses pre-built package, or errors if project is not built.");
+    console.log("    --archs       : Specific chip architectures (`anycpu`, `arm`, `x86`, `x64`).");
+    console.log("    --phone, --win");
+    console.log("                  : Specifies project type to deploy");
+    console.log("");
+    console.log("Examples:");
+    console.log("    run");
+    console.log("    run --emulator");
+    console.log("    run --device");
+    console.log("    run --target=7988B8C3-3ADE-488d-BA3E-D052AC9DC710");
+    console.log("    run --device --release");
+    console.log("    run --emulator --debug");
+    console.log("");
+    process.exit(0);
+};
+
+
+function getWindowsTargetVersion() {
+    var config = new ConfigParser(path.join(ROOT, 'config.xml'));
+    var windowsTargetVersion = config.getPreference('windows-target-version')
+    switch(windowsTargetVersion) {
+    case '8':
+    case '8.0':
+        return '8.0'
+    case '8.1':
+        return '8.1'
+    default:
+        throw new Error('Unsupported windows-target-version value: ' + windowsTargetVersion)
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/f4e2ac6a/template/cordova/lib/spawn.js
----------------------------------------------------------------------
diff --git a/template/cordova/lib/spawn.js b/template/cordova/lib/spawn.js
new file mode 100644
index 0000000..0ccb0f5
--- /dev/null
+++ b/template/cordova/lib/spawn.js
@@ -0,0 +1,40 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var Q    = require('q'),
+    proc = require('child_process');
+
+// Takes a command and optional current working directory.
+module.exports = function(cmd, args, opt_cwd) {
+    var d = Q.defer();
+    try {
+        var child = proc.spawn(cmd, args, {cwd: opt_cwd, stdio: 'inherit'});
+        child.on('exit', function(code) {
+            if (code) {
+                d.reject('Error code ' + code + ' for command: ' + cmd + ' with args: ' + args);
+            } else {
+                d.resolve();
+            }
+        });
+    } catch(e) {
+        console.error('error caught: ' + e);
+        d.reject(e);
+    }
+    return d.promise;
+};

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/f4e2ac6a/template/cordova/lib/utils.js
----------------------------------------------------------------------
diff --git a/template/cordova/lib/utils.js b/template/cordova/lib/utils.js
new file mode 100644
index 0000000..c409b86
--- /dev/null
+++ b/template/cordova/lib/utils.js
@@ -0,0 +1,93 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+var Q     = require('Q'),
+    fs    = require('fs'),
+    path  = require('path'),
+    exec  = require('./exec'),
+    spawn = require('./spawn');
+
+// returns full path to msbuild tools required to build the project and tools version
+module.exports.getMSBuildTools = function () {
+    var versions = ['12.0', '4.0'];
+    // create chain of promises, which returns specific msbuild version object
+    // or null, if specific msbuild path not found in registry
+    return Q.all(versions.map(function (version) {
+        return exec(
+            'reg query HKLM\\SOFTWARE\\Microsoft\\MSBuild\\ToolsVersions\\' + version + ' /v MSBuildToolsPath'
+        ).then(function(output) {
+            // fetch msbuild path from 'reg' output
+            var msbPath = /MSBuildToolsPath\s+REG_SZ\s+(.*)/i.exec(output);
+            if (msbPath) {
+                return {version: version, path: msbPath[1]};
+            }
+            return null;
+        });
+    })).then(function (versions) {
+        // select first msbuild version available, and resolve promise with it
+        return versions[0] || versions[1] ?
+            Q.resolve(versions[0] || versions[1]) :
+            // Reject promise if no msbuild versions found
+            Q.reject('MSBuild tools not found');
+    });
+};
+
+// unblocks and returns path to WindowsStoreAppUtils.ps1
+// which provides helper functions to install/unistall/start Windows Store app
+module.exports.getAppStoreUtils = function () {
+    var appStoreUtils = path.join(__dirname, 'WindowsStoreAppUtils.ps1');
+    if (!fs.existsSync (appStoreUtils)) {
+        return Q.reject("Can't unblock AppStoreUtils script");
+    }
+    //console.log("Removing execution restrictions from AppStoreUtils...");
+    return spawn('powershell', ['Unblock-File', module.exports.quote(appStoreUtils)]).then(function () {
+        return Q.resolve(appStoreUtils);
+    }).fail(function (err) {
+        return Q.reject(err);
+    });
+};
+
+// returns path to AppDeploy util from Windows Phone 8.1 SDK
+module.exports.getAppDeployUtils = function () {
+    var appDeployUtils = path.join((process.env["ProgramFiles(x86)"] || process.env["ProgramFiles"]),
+        'Microsoft SDKs', 'Windows Phone', 'v8.1', 'Tools', 'AppDeploy', 'AppDeployCmd.exe');
+    // Check if AppDeployCmd is exists
+    if (!fs.existsSync(appDeployUtils)) {
+        console.warn("WARNING: AppDeploy tool (AppDeployCmd.exe) didn't found. Assume that it's in %PATH%");
+        return Q.resolve("AppDeployCmd");
+    }
+    return Q.resolve(appDeployUtils);
+};
+
+// checks to see if a .jsproj file exists in the project root
+module.exports.isCordovaProject = function (platformpath) {
+    if (fs.existsSync(platformpath)) {
+        var files = fs.readdirSync(platformpath);
+        for (var i in files){
+            if (path.extname(files[i]) == '.shproj'){
+                return true;
+            }
+        }
+    }
+    return false;
+};
+
+module.exports.quote = function(str) {
+    return '"' + str + '"';
+};

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/f4e2ac6a/template/cordova/log.bat
----------------------------------------------------------------------
diff --git a/template/cordova/log.bat b/template/cordova/log.bat
new file mode 100644
index 0000000..d23aeab
--- /dev/null
+++ b/template/cordova/log.bat
@@ -0,0 +1,19 @@
+:: Licensed to the Apache Software Foundation (ASF) under one
+:: or more contributor license agreements.  See the NOTICE file
+:: distributed with this work for additional information
+:: regarding copyright ownership.  The ASF licenses this file
+:: to you under the Apache License, Version 2.0 (the
+:: "License"); you may not use this file except in compliance
+:: with the License.  You may obtain a copy of the License at
+:: 
+:: http://www.apache.org/licenses/LICENSE-2.0
+:: 
+:: Unless required by applicable law or agreed to in writing,
+:: software distributed under the License is distributed on an
+:: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+:: KIND, either express or implied.  See the License for the
+:: specific language governing permissions and limitations
+:: under the License
+@ECHO OFF
+ECHO Sorry, logging is not supported for Windows. 1>&2
+EXIT /B 1
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/f4e2ac6a/template/cordova/node_modules/.bin/nopt
----------------------------------------------------------------------
diff --git a/template/cordova/node_modules/.bin/nopt b/template/cordova/node_modules/.bin/nopt
new file mode 100644
index 0000000..25995f3
--- /dev/null
+++ b/template/cordova/node_modules/.bin/nopt
@@ -0,0 +1,15 @@
+#!/bin/sh
+basedir=`dirname "$0"`
+
+case `uname` in
+    *CYGWIN*) basedir=`cygpath -w "$basedir"`;;
+esac
+
+if [ -x "$basedir/node" ]; then
+  "$basedir/node"  "$basedir/../nopt/bin/nopt.js" "$@"
+  ret=$?
+else 
+  node  "$basedir/../nopt/bin/nopt.js" "$@"
+  ret=$?
+fi
+exit $ret

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/f4e2ac6a/template/cordova/node_modules/.bin/nopt.cmd
----------------------------------------------------------------------
diff --git a/template/cordova/node_modules/.bin/nopt.cmd b/template/cordova/node_modules/.bin/nopt.cmd
new file mode 100644
index 0000000..c8e8216
--- /dev/null
+++ b/template/cordova/node_modules/.bin/nopt.cmd
@@ -0,0 +1,5 @@
+@IF EXIST "%~dp0\node.exe" (
+  "%~dp0\node.exe"  "%~dp0\..\nopt\bin\nopt.js" %*
+) ELSE (
+  node  "%~dp0\..\nopt\bin\nopt.js" %*
+)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/f4e2ac6a/template/cordova/node_modules/elementtree/.npmignore
----------------------------------------------------------------------
diff --git a/template/cordova/node_modules/elementtree/.npmignore b/template/cordova/node_modules/elementtree/.npmignore
new file mode 100644
index 0000000..3c3629e
--- /dev/null
+++ b/template/cordova/node_modules/elementtree/.npmignore
@@ -0,0 +1 @@
+node_modules

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/f4e2ac6a/template/cordova/node_modules/elementtree/.travis.yml
----------------------------------------------------------------------
diff --git a/template/cordova/node_modules/elementtree/.travis.yml b/template/cordova/node_modules/elementtree/.travis.yml
new file mode 100644
index 0000000..6f27c96
--- /dev/null
+++ b/template/cordova/node_modules/elementtree/.travis.yml
@@ -0,0 +1,10 @@
+language: node_js
+
+node_js:
+  - 0.6
+
+script: make test
+
+notifications:
+  email:
+    - tomaz+travisci@tomaz.me

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/f4e2ac6a/template/cordova/node_modules/elementtree/CHANGES.md
----------------------------------------------------------------------
diff --git a/template/cordova/node_modules/elementtree/CHANGES.md b/template/cordova/node_modules/elementtree/CHANGES.md
new file mode 100644
index 0000000..83bd61b
--- /dev/null
+++ b/template/cordova/node_modules/elementtree/CHANGES.md
@@ -0,0 +1,34 @@
+elementtree v0.1.5 (in development)
+
+* Fix a bug in the find() and findtext() method which could manifest itself
+  under some conditions.
+  [metagriffin]
+
+elementtree v0.1.4
+
+* Allow user to use namespaced attributes when using find* functions.
+  [Andrew Lunny]
+
+elementtree v0.1.3
+
+* Improve the output of text content in the tags (strip unnecessary line break
+  characters).
+
+[Darryl Pogue]
+
+elementtree v0.1.2
+
+ * Allow user to pass 'indent' option to ElementTree.write method. If this
+   option is specified (e.g. {'indent': 4}). XML will be pretty printed.
+   [Darryl Pogue, Tomaz Muraus]
+
+ * Bump sax dependency version.
+
+elementtree v0.1.1 - 2011-09-23
+
+ * Improve special character escaping.
+   [Ryan Phillips]
+
+elementtree v0.1.0 - 2011-09-05
+
+ * Initial release.

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/f4e2ac6a/template/cordova/node_modules/elementtree/LICENSE.txt
----------------------------------------------------------------------
diff --git a/template/cordova/node_modules/elementtree/LICENSE.txt b/template/cordova/node_modules/elementtree/LICENSE.txt
new file mode 100644
index 0000000..6b0b127
--- /dev/null
+++ b/template/cordova/node_modules/elementtree/LICENSE.txt
@@ -0,0 +1,203 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/f4e2ac6a/template/cordova/node_modules/elementtree/Makefile
----------------------------------------------------------------------
diff --git a/template/cordova/node_modules/elementtree/Makefile b/template/cordova/node_modules/elementtree/Makefile
new file mode 100644
index 0000000..ab7c4e0
--- /dev/null
+++ b/template/cordova/node_modules/elementtree/Makefile
@@ -0,0 +1,21 @@
+TESTS := \
+	tests/test-simple.js
+
+
+
+PATH := ./node_modules/.bin:$(PATH)
+
+WHISKEY := $(shell bash -c 'PATH=$(PATH) type -p whiskey')
+
+default: test
+
+test:
+	NODE_PATH=`pwd`/lib/ ${WHISKEY} --scope-leaks --sequential --real-time --tests "${TESTS}"
+
+tap:
+	NODE_PATH=`pwd`/lib/ ${WHISKEY} --test-reporter tap --sequential --real-time --tests "${TESTS}"
+
+coverage:
+	NODE_PATH=`pwd`/lib/ ${WHISKEY} --sequential --coverage  --coverage-reporter html --coverage-dir coverage_html --tests "${TESTS}"
+
+.PHONY: default test coverage tap scope

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/f4e2ac6a/template/cordova/node_modules/elementtree/NOTICE
----------------------------------------------------------------------
diff --git a/template/cordova/node_modules/elementtree/NOTICE b/template/cordova/node_modules/elementtree/NOTICE
new file mode 100644
index 0000000..28ad70a
--- /dev/null
+++ b/template/cordova/node_modules/elementtree/NOTICE
@@ -0,0 +1,5 @@
+node-elementtree
+Copyright (c) 2011, Rackspace, Inc.
+
+The ElementTree toolkit is Copyright (c) 1999-2007 by Fredrik Lundh
+

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/f4e2ac6a/template/cordova/node_modules/elementtree/README.md
----------------------------------------------------------------------
diff --git a/template/cordova/node_modules/elementtree/README.md b/template/cordova/node_modules/elementtree/README.md
new file mode 100644
index 0000000..8a7e710
--- /dev/null
+++ b/template/cordova/node_modules/elementtree/README.md
@@ -0,0 +1,27 @@
+node-elementtree
+====================
+
+node-elementtree is a [Node.js](http://nodejs.org) XML parser and serializer based upon the [Python ElementTree v1.3](http://effbot.org/zone/element-index.htm) module.
+
+Installation
+====================
+
+    $ npm install elementtree
+    
+Using the library
+====================
+
+For the usage refer to the Python ElementTree library documentation - [http://effbot.org/zone/element-index.htm#usage](http://effbot.org/zone/element-index.htm#usage).
+
+Supported XPath expressions in `find`, `findall` and `findtext` methods are listed on [http://effbot.org/zone/element-xpath.htm](http://effbot.org/zone/element-xpath.htm).
+
+Build status
+====================
+
+[![Build Status](https://secure.travis-ci.org/racker/node-elementtree.png)](http://travis-ci.org/racker/node-elementtree)
+
+
+License
+====================
+
+node-elementtree is distributed under the [Apache license](http://www.apache.org/licenses/LICENSE-2.0.html).

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/f4e2ac6a/template/cordova/node_modules/elementtree/lib/constants.js
----------------------------------------------------------------------
diff --git a/template/cordova/node_modules/elementtree/lib/constants.js b/template/cordova/node_modules/elementtree/lib/constants.js
new file mode 100644
index 0000000..b057faf
--- /dev/null
+++ b/template/cordova/node_modules/elementtree/lib/constants.js
@@ -0,0 +1,20 @@
+/*
+ *  Copyright 2011 Rackspace
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+var DEFAULT_PARSER = 'sax';
+
+exports.DEFAULT_PARSER = DEFAULT_PARSER;

http://git-wip-us.apache.org/repos/asf/cordova-windows/blob/f4e2ac6a/template/cordova/node_modules/elementtree/lib/elementpath.js
----------------------------------------------------------------------
diff --git a/template/cordova/node_modules/elementtree/lib/elementpath.js b/template/cordova/node_modules/elementtree/lib/elementpath.js
new file mode 100644
index 0000000..2e93f47
--- /dev/null
+++ b/template/cordova/node_modules/elementtree/lib/elementpath.js
@@ -0,0 +1,343 @@
+/**
+ *  Copyright 2011 Rackspace
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ */
+
+var sprintf = require('./sprintf').sprintf;
+
+var utils = require('./utils');
+var SyntaxError = require('./errors').SyntaxError;
+
+var _cache = {};
+
+var RE = new RegExp(
+  "(" +
+  "'[^']*'|\"[^\"]*\"|" +
+  "::|" +
+  "//?|" +
+  "\\.\\.|" +
+  "\\(\\)|" +
+  "[/.*:\\[\\]\\(\\)@=])|" +
+  "((?:\\{[^}]+\\})?[^/\\[\\]\\(\\)@=\\s]+)|" +
+  "\\s+", 'g'
+);
+
+var xpath_tokenizer = utils.findall.bind(null, RE);
+
+function prepare_tag(next, token) {
+  var tag = token[0];
+
+  function select(context, result) {
+    var i, len, elem, rv = [];
+
+    for (i = 0, len = result.length; i < len; i++) {
+      elem = result[i];
+      elem._children.forEach(function(e) {
+        if (e.tag === tag) {
+          rv.push(e);
+        }
+      });
+    }
+
+    return rv;
+  }
+
+  return select;
+}
+
+function prepare_star(next, token) {
+  function select(context, result) {
+    var i, len, elem, rv = [];
+
+    for (i = 0, len = result.length; i < len; i++) {
+      elem = result[i];
+      elem._children.forEach(function(e) {
+        rv.push(e);
+      });
+    }
+
+    return rv;
+  }
+
+  return select;
+}
+
+function prepare_dot(next, token) {
+  function select(context, result) {
+    var i, len, elem, rv = [];
+
+    for (i = 0, len = result.length; i < len; i++) {
+      elem = result[i];
+      rv.push(elem);
+    }
+
+    return rv;
+  }
+
+  return select;
+}
+
+function prepare_iter(next, token) {
+  var tag;
+  token = next();
+
+  if (token[1] === '*') {
+    tag = '*';
+  }
+  else if (!token[1]) {
+    tag = token[0] || '';
+  }
+  else {
+    throw new SyntaxError(token);
+  }
+
+  function select(context, result) {
+    var i, len, elem, rv = [];
+
+    for (i = 0, len = result.length; i < len; i++) {
+      elem = result[i];
+      elem.iter(tag, function(e) {
+        if (e !== elem) {
+          rv.push(e);
+        }
+      });
+    }
+
+    return rv;
+  }
+
+  return select;
+}
+
+function prepare_dot_dot(next, token) {
+  function select(context, result) {
+    var i, len, elem, rv = [], parent_map = context.parent_map;
+
+    if (!parent_map) {
+      context.parent_map = parent_map = {};
+
+      context.root.iter(null, function(p) {
+        p._children.forEach(function(e) {
+          parent_map[e] = p;
+        });
+      });
+    }
+
+    for (i = 0, len = result.length; i < len; i++) {
+      elem = result[i];
+
+      if (parent_map.hasOwnProperty(elem)) {
+        rv.push(parent_map[elem]);
+      }
+    }
+
+    return rv;
+  }
+
+  return select;
+}
+
+
+function prepare_predicate(next, token) {
+  var tag, key, value, select;
+  token = next();
+
+  if (token[1] === '@') {
+    // attribute
+    token = next();
+
+    if (token[1]) {
+      throw new SyntaxError(token, 'Invalid attribute predicate');
+    }
+
+    key = token[0];
+    token = next();
+
+    if (token[1] === ']') {
+      select = function(context, result) {
+        var i, len, elem, rv = [];
+
+        for (i = 0, len = result.length; i < len; i++) {
+          elem = result[i];
+
+          if (elem.get(key)) {
+            rv.push(elem);
+          }
+        }
+
+        return rv;
+      };
+    }
+    else if (token[1] === '=') {
+      value = next()[1];
+
+      if (value[0] === '"' || value[value.length - 1] === '\'') {
+        value = value.slice(1, value.length - 1);
+      }
+      else {
+        throw new SyntaxError(token, 'Ivalid comparison target');
+      }
+
+      token = next();
+      select = function(context, result) {
+        var i, len, elem, rv = [];
+
+        for (i = 0, len = result.length; i < len; i++) {
+          elem = result[i];
+
+          if (elem.get(key) === value) {
+            rv.push(elem);
+          }
+        }
+
+        return rv;
+      };
+    }
+
+    if (token[1] !== ']') {
+      throw new SyntaxError(token, 'Invalid attribute predicate');
+    }
+  }
+  else if (!token[1]) {
+    tag = token[0] || '';
+    token = next();
+
+    if (token[1] !== ']') {
+      throw new SyntaxError(token, 'Invalid node predicate');
+    }
+
+    select = function(context, result) {
+      var i, len, elem, rv = [];
+
+      for (i = 0, len = result.length; i < len; i++) {
+        elem = result[i];
+
+        if (elem.find(tag)) {
+          rv.push(elem);
+        }
+      }
+
+      return rv;
+    };
+  }
+  else {
+    throw new SyntaxError(null, 'Invalid predicate');
+  }
+
+  return select;
+}
+
+
+
+var ops = {
+  "": prepare_tag,
+  "*": prepare_star,
+  ".": prepare_dot,
+  "..": prepare_dot_dot,
+  "//": prepare_iter,
+  "[": prepare_predicate,
+};
+
+function _SelectorContext(root) {
+  this.parent_map = null;
+  this.root = root;
+}
+
+function findall(elem, path) {
+  var selector, result, i, len, token, value, select, context;
+
+  if (_cache.hasOwnProperty(path)) {
+    selector = _cache[path];
+  }
+  else {
+    // TODO: Use smarter cache purging approach
+    if (Object.keys(_cache).length > 100) {
+      _cache = {};
+    }
+
+    if (path.charAt(0) === '/') {
+      throw new SyntaxError(null, 'Cannot use absolute path on element');
+    }
+
+    result = xpath_tokenizer(path);
+    selector = [];
+
+    function getToken() {
+      return result.shift();
+    }
+
+    token = getToken();
+    while (true) {
+      var c = token[1] || '';
+      value = ops[c](getToken, token);
+
+      if (!value) {
+        throw new SyntaxError(null, sprintf('Invalid path: %s', path));
+      }
+
+      selector.push(value);
+      token = getToken();
+
+      if (!token) {
+        break;
+      }
+      else if (token[1] === '/') {
+        token = getToken();
+      }
+
+      if (!token) {
+        break;
+      }
+    }
+
+    _cache[path] = selector;
+  }
+
+  // Execute slector pattern
+  result = [elem];
+  context = new _SelectorContext(elem);
+
+  for (i = 0, len = selector.length; i < len; i++) {
+    select = selector[i];
+    result = select(context, result);
+  }
+
+  return result || [];
+}
+
+function find(element, path) {
+  var resultElements = findall(element, path);
+
+  if (resultElements && resultElements.length > 0) {
+    return resultElements[0];
+  }
+
+  return null;
+}
+
+function findtext(element, path, defvalue) {
+  var resultElements = findall(element, path);
+
+  if (resultElements && resultElements.length > 0) {
+    return resultElements[0].text;
+  }
+
+  return defvalue;
+}
+
+
+exports.find = find;
+exports.findall = findall;
+exports.findtext = findtext;